Description
Input
第一行输入一个T (1 <T< 10),表示有多少组数据
每一组数据:
第一行输入一个N (1 < N<10^5),表示数列的长度
第二行输入N个数A_1, A_2, ..., A_n。
每一个数列中的元素都是正整数而且不超过10^6。
Output
对于每组数据,先输出一行
Case #i:
然后输出最少需要修改多少个元素。
Sample Input
Sample Output
我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增。其中无论是修改前还是修改后,每个元素都必须是整数。
请输出最少需要修改多少个元素。
请输出最少需要修改多少个元素。
每一组数据:
第一行输入一个N (1 < N<10^5),表示数列的长度
第二行输入N个数A_1, A_2, ..., A_n。
每一个数列中的元素都是正整数而且不超过10^6。
Case #i:
然后输出最少需要修改多少个元素。
2 2 1 10 3 2 5 4
Case #1: 0 Case #2: 1
解析:
考虑序列限制条件为a[i]-a[j]>=i-j(线性非递减)
=====> a[i]-i>=a[j]-j
所以考虑建数组b[i]=a[i]-i
则问题转换为求数组b[i]的不递减序列的长度l
则最后结果为n-l+1
程序如下:
#include<cstdio> #define INF 0X3f3f3f3f; int n,l; int a[100200]; int s[100200]; int find(int m) { int la=0,lb=l; while(lb>=la) { int mid=(la+lb)/2; if(s[mid]>m) lb=mid-1; else la=mid+1; } return la; } int main() { int T,Case=1; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1; i<=n; i++) { int t; scanf("%d",&t); a[i]=t-i; } s[0]=-INF; l=1; for(int i=1; i<=n; i++) { s[l]=INF; int t=find(a[i]); if(t==l) l++; s[t]=a[i]; } printf("Case #%d:\n",Case++); printf("%d\n",n-l+1); } return 0; }