题面
【问题描述】
一个数组的元素为 \(1\) 至 \(N\) 的整数,现在要对这个数组进行排序,在排序时只能将元素放在数组的头部或尾部,问至少需要移动多少个数字,才能完成整个排序过程?
例如:
25341将1移到头部⇒12534;
将5移到尾部⇒12345;这样就排好了,移动了 2 个元素。
给出一个 \(1\) 到 \(N\) 的排列,输出完成排序所需的最少移动次数。
【输入描述】
第 \(1\) 行:1 个数 \(N\) (\(2\le N\le 50000\))
第 \(2\) ~ \(N+1\) 行:每行 1 个数,对应排列中的元素。
【输出描述】
输出 1 个数,对应所需的最少移动次数。
【输入样例】
5
2
5
3
4
1
【输出样例】
2
【数据范围】
对于 \(30\%\) 的数据,\(N\le 100\)
对于 \(50\%\) 的数据,\(N\le 1000\)
对于 \(100\%\) 的数据,\(N\le 50000\)
解
对于所有的排列,理所应当地都要把中间元素以下的移到最前,剩下的移到最后,而连续的子串不需要处理。只需要求出最长连续子串的长度,再用 \(n\) 减就是答案。
程序
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define MAXN 50050
int a[MAXN], n, d[MAXN];
int main() {
memset(d, 0, sizeof(d));
cin >> n; for (int i = 0; i < n; i++) cin >> a[i];
int ans = n;
for (int i = 0; i < n; i++) {
d[a[i]] = d[a[i] - 1] + 1;
ans = min(ans, n - d[a[i]]);
}
cout << ans << endl;
return 0;
}