51Nod 1241 特殊的排序

题目传送门

 

分析:之前想的是求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;
}


 

你可能感兴趣的:(51Nod 1241 特殊的排序)