百度之星 2015 初赛(2) 1005 序列变换

来源:互联网 发布:淘宝怎么预防死人衣服 编辑:程序博客网 时间:2024/06/05 14:36

序列变换

 
 Accepts: 695
 
 Submissions: 3322
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 32768/32768 K (Java/Others)
Problem Description

我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增。其中无论是修改前还是修改后,每个元素都必须是整数。 请输出最少需要修改多少个元素。

Input

第一行输入一个T(1T10),表示有多少组数据

每一组数据:

第一行输入一个N(1N105),表示数列的长度

第二行输入N个数A1,A2,...,An

每一个数列中的元素都是正整数而且不超过106

Output

对于每组数据,先输出一行

Case #i:

然后输出最少需要修改多少个元素。

Sample Input
221 1032 5 4
Sample Output
Case #1:0Case #2:1
解题思路:

最长非严格单调递增子序列。


#include <stdio.h>int GetPosition(int c[], int len, int i, int X[]){    int start = 1;    int end = len;    while (start <= end)    {        int mid = (start + end) / 2;        if (X[c[mid]] <= X[i]) {            start = mid + 1;        }        else {            end =  mid - 1;        }    }    return start;}int LongestIncreasingSubsequence(int X[], int n){    int c[n], path[n];    c[0] = -1;    c[1] = 0;    int line[n];    line[0] = c[0];    int len = 1;    for (int i = 1; i < n; ++i)    {        int index = GetPosition(c, len, i, X);        line[i] = c[index - 1];        c[index] = i;        if (index > len) {            len = index;        }    }    path[0] = c[len];    int i = 0;    while (line[path[i]] != -1)    {        path[i + 1] = line[path[i]];        ++i;    }    return len;}int main() {    int T,i,j,it;    scanf("%d", &T);    for(i = 1; i <= T; i++) {        int N;        scanf("%d", &N);        int a[N];        for(j = 0; j < N; j++) {scanf("%d", a+j);a[j]-=j;};        int r = LongestIncreasingSubsequence(a, N);        printf("Case #%d:\n",i);        printf("%d\n", N - r);    }    return 0;}


0 0
原创粉丝点击