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;
}


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值