51nod 1294 修改数组(dp,逆向思维,最大上升子序列)

来源:互联网 发布:淘宝双11海报素材 编辑:程序博客网 时间:2024/05/18 02:48

------------------------------------看别人的代码写得题解---------------------------------------

这个题和那个最大上升子序列很像,就是不是严格递增的最大上升自序列。首先应该去想如果a[i]-i小于0,必须要改,因为这个是按照严格的递增来排列的。剩下的就要找不是严格递增的最大上升自序列。用n-最大上升自序列,就是答案。

如果自己去想肯定很难想到了,如果看了答案又会感觉很简单的啦。如果a[i]都减去i,不是严格递增的最大上升自序列一定就是不用改变值的个数,其他的数第i位只需要改变成i就够了。


----------------------------------------自己的感想-------------------------------------------------------

这就是逆向思维了,只听别人说答案怎么地怎么地,下次就能做出来?不存在的。你想的去求不改变的个数是多少。先去掉必须改变的个数,然后去求不是严格递增的最大上升自序列,这个是最大的不用改变的数,应该能看懂。其他的数第i位只需要改变成i就够了。

#include <bits\stdc++.h>using namespace std;#define fo(i,a,b) for(i=a;i<=b;i++)const int maxn=1e5+7;int i,j,k,l,t,n,m,ans,r,mid;int a[maxn],f[maxn],b[maxn];int main(){    scanf("%d",&n);    fo(i,1,n)scanf("%d",&a[i]),a[i]-=i,f[i]=1e9+2;    fo(i,1,n){        if(a[i]>=0)b[++b[0]]=a[i];    }   ans=0;   for(int i=1;i<=b[0];i++)    {    int tmp=lower_bound(f+1,f+1+ans,b[i])-f;    while(b[i]==f[tmp])tmp++;    f[tmp]=b[i];    ans=max(tmp,ans);    }    printf("%d\n",n-ans);}


原创粉丝点击