分析:之前想的是求LIS,后面发现这组数据会出问题:3 1 2 4 5 6。
其实这里的LIS还应当满足前后两个元素的值相差为1。比如上面的最长子序列为:3 4 5 6,而不是1 2 4 5 6。即只需移动1、2即可。
即如果n个数最长连续上升子序列(这里的连续指数值上连续,即前后相差1)长度为k,则最少移动次数为n-k
简略证明:
首先需要证明:最少移动次数和移动数的个数是相等的,即每个数最多只移动一次。因为最终每个数的位置是确定的,若一个数需要移动,只需一次移动到该位置即可。
假设存在更优的移动方案,移动次数为m,即移动m(m<n-k)个数。那么剩下n-m (>k)个数是不需要移动的,这样n-m个数构成了更长的连续上升子序列。矛盾!
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[50005],b[50005];
int main()
{
int ans,n;
while(~scanf("%d",&n))
{
memset(b,0,sizeof(b));
ans=0;
for(int i=1;i<=n;++i) {scanf("%d",&a[i]);b[a[i]]=b[a[i]-1]+1;ans=max(ans,b[a[i]]);}
printf("%d\n",n-ans);
}
return 0;
}