hdu5256【序列变换】【LIS】

来源:互联网 发布:从应用程序中提取sql 编辑:程序博客网 时间:2024/05/20 19:45
Description
我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增。其中无论是修改前还是修改后,每个元素都必须是整数。 
请输出最少需要修改多少个元素。
Input
第一行输入一个T (1 <T< 10),表示有多少组数据 

每一组数据: 

第一行输入一个N (1 < N<10^5),表示数列的长度 

第二行输入N个数A_1, A_2, ..., A_n。 

每一个数列中的元素都是正整数而且不超过10^6。
Output
对于每组数据,先输出一行 

Case #i: 

然后输出最少需要修改多少个元素。
Sample Input
221 1032 5 4
Sample Output
Case #1:0Case #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;}


原创粉丝点击