------------------------------------看别人的代码写得题解---------------------------------------
这个题和那个最大上升子序列很像,就是不是严格递增的最大上升自序列。首先应该去想如果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);
}