给力的移动 FZU

你的弟弟给你安排了一个任务,他给了你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-maxn);
22     }
23 }
View Code


原文地址:https://www.cnblogs.com/iwannabe/p/9150013.html