其实主要在思维
答案就是:不是在最长公差为1子序列 的个数
什么意思呢?
“公差为1序列:就是1 2 3 , 5 6 7 8 9, 4 5 6这种连续自然数(必须上升)
eg.
7
3 5 4 6 1 7 2
最长公差为1子序列:5 6 7
所以答案为:7 - 3 = 4
我们设这个序列为
在最长公差为1子序列,
不在此序列的是移动为,
操作方法:
如果把不在子序列内的数分为两个集合,
和
则我们按倒序分别放到序列开头,按正序放到序列末尾,就必定是升序
eg. 3 5 4 6 1 8 7 2
4 3 5 6 1 8 7 2(4)
3 4 5 6 1 8 7 2(3)
2 3 4 5 6 1 8 7(2)
1 2 3 4 5 6 8 7(1)
1 2 3 4 5 6 7 8(8)
现在要求证:
所以非d的元素必须聚拢在一起,一定是最长公差为1序列,所以剩下来的就是b
所以,移动的就是c,即c=d
上代码:
注意:
用dp[i]表示前i个数的最长公差为1子序列长度
loc[x]=x所在a的位置
每次考loc计算dp
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 7, M = 1e3 + 7;
#define int long long
int n, a[N], loc[N], dp[N];
signed main() {
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> a[i], loc[a[i]] = i;
for (int i = 1; i <= n; ++i) {
int p = loc[a[i] - 1];
if (i < p) dp[i] = 1;
else dp[i] = dp[p] + 1;
}
cout << n - (*max_element(dp + 1, dp + n + 1));
return 0;
}