2015.9.4组队赛第3场1005

来源:互联网 发布:java转义字符表 编辑:程序博客网 时间:2024/06/06 09:43

递增序列

Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 8   Accepted Submission(s) : 4

Font: Times New Roman | Verdana | Georgia

Font Size:  

Problem Description

给定一个数列{an},修改数列中的某些元素,使得数列严格递增,求最小的修改数。

Input

第一行一个正整数t,测试数据组数。
每组数据第一行一个正整数n (n<=100000)。
第二行n个正整数ai(1<=ai<=100000)。

Output

每组数据输出一个正整数,如题述。

Sample Input

142 3 3 3

Sample Output

2

思路:找最长的不用修改的一个序列,那这个序列的的元素应该要满足这样子的一个条件(a[j]-a[i])>=(j-i)(其中j>i),然后转换一下式子就是(a[j]-j)>=(a[i]-i),那么我们就可以把问题转化为求数列{a[n]-n}的最长上升子序列,不需要连续。参考大白62页

#pragma comment(linker, "/STACK:1024000000,1024000000")#pragma warning(disable:4996)#include<set>#include<map>#include<queue>#include<stack>#include<cmath>#include<cstdio>#include<vector>#include<string>#include<cstring>#include<algorithm>#include<functional>#include<iostream>#define INF 0x3f3f3f3f#define LL long long#define min(a,b) a>b?b:ausing namespace std;int a[1000000];int g[1000000];//g[i]d值为i的最小状态编号,即d[j]=i的最小的jint d[1000000];//d[ii]以i结尾id最长上升子序列长度int main(){int t;scanf("%d", &t);int n;while (t--){scanf("%d", &n);for (int i = 0; i < n; i++){scanf("%d", &a[i]);a[i] = a[i] - i;}for (int i = 1; i <= n; i++)g[i] = INF;for (int i = 0; i < n; i++){int k = upper_bound(g + 1, g + n + 1, a[i]) - g;d[i] = k;g[k] = a[i];}int res = -1;for (int i = 0; i < n; i++)res = max(res, d[i]);printf("%d\n", n-res);}return 0;}



0 0
原创粉丝点击