给力的移动 FZU - 2287

你的弟弟给你安排了一个任务,他给了你1到N个数字的乱序排列,现在你想给你的弟弟秀一波操作,操作最少的次数把序列变成1到N的顺序排列,每次操作你可以选择序列中的一个数字并把它移动到序列的头部或尾部。

Input

包含多组测试数据。

每组测试数据的第一行为正整数N,表示排列的长度。

第二行为N个数字的乱序排列。

n≤100000

Output

输出最少的操作次数

Sample Input

6
6 3 2 4 5 1

Sample Output

3


em 很简单的思维题啊,可是我比赛的时候还是没想到,哭死
如果要最小化这个操作数的话,要移动在值上并不是相邻的数,因为值相邻的话,那我就不必移动这些数,只需要将其他的数按一定的顺序向两头移动就好
那么我们就要找到这个最长的值相邻的子序列 然后剩下的数就是要移动的

这里就是用一个数组记录在这个数输入前,它的前一个数是否出现,如果不出现,它就是序列的头(0+1),如果出现,就继承前面数之前有的数(num+1).
找到其中的最大值就好了
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string.h>
 4 using namespace std;
 5 
 6 int ans[100005];
 7 int main()
 8 {
 9     int n;
10     while(~scanf("%d",&n))
11     {
12         int temp;
13         memset(ans,0,sizeof(ans));
14         int maxn = 0;
15         for(int i=0;i<n;i++)
16         {
17             scanf("%d",&temp);
18             ans[temp] = ans[temp-1] + 1;
19             maxn = max(maxn,ans[temp]);
20         }
21         printf("%d\n",n-maxn);
22     }
23 }
View Code

 



转载于:https://www.cnblogs.com/iwannabe/p/9150013.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值