51nod 1241 特殊的排序(动态规划)

 

  分析:记数组中最长的连续子串长度为maxlen(数值上连续,位置不一定连续,如2134,最长为3).首先可以证明,n-maxlen次操作可以满足条件,如最长子串最后一个为x<n,则把x+1移到最后,如果是x=n,记子串的第一个为y,把y-1移到最前,每次操作后最长连续子串长度+1,故可以满足条件.接下来证明,这是最少的移动次数.假设还有更少的,说明存在一步移动,最长连续子串长度至少+2,但移走一个元素不增加长度,把这个元素放在最前或最后最多只能增加1,矛盾.

  求maxlen动态规划一下,记dp[x]为数字x开头的最长连续子串长度,则if(x+1在x后面)dp[x]=dp[x+1]+1,else dp[x]=1.复杂度为O(n).

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int maxn=50005;
 5 int n,dp[maxn],loca[maxn];
 6 int main(){
 7     memset(dp,0,sizeof(dp));
 8     cin>>n;
 9     int a;
10     for(int i=0;i<n;i++){
11         cin>>a;
12         loca[a-1]=i;
13     }
14     dp[n-1]=1;
15     for(int i=n-2;i>=0;i--){
16         if(loca[i+1]>loca[i])
17             dp[i]=dp[i+1]+1;
18         else
19             dp[i]=1;
20     }
21     int maxlen=0;
22     for(int i=0;i<n;i++){
23         if(dp[i]>maxlen)maxlen=dp[i];
24     }
25     cout<<n-maxlen<<endl;
26     return 0;
27 }

 

转载于:https://www.cnblogs.com/7391-KID/p/7061409.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值