题意
思路
数组位置 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
元素值 | z | - | - | w | x | y |
首先给出结论:对于第i个位置,插入到任意位置所需要的次数为1
证明:
考虑第n个位置,如图所示n=6
y如何插入到w与x之间
操作1:xz–wy
操作2:z–wyx
y如何插入到-与w之间
操作1:xz–wy | wxz–y
操作2:z-ywx
以此类推,就可以让第n个位置插入到任意位置
那我们如何证明对于任意i呢?
首先通过操作1,把第1…i位置全部移动到后面,
即a[i+1], a[i+2],…a[n],a[1],…,a[i]。
这样就可以把a[i]移动到任意位置,移动完毕后,把a[i+1],a[i+2],…a[n]移动到a[1],…,a[i-1]后面。
举例:
w如何插入到x与y之间
操作2:xyz–w
操作1和2(已证):xwyz–
操作2:z–xwy
证毕。
补一发AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1100;
int n;
int p[maxn], dp[maxn];
int solve(int l, int r){
int len = 1;
dp[1] = p[l];
for(int i = l + 1; i <= r; i++){
if(dp[len] <= p[i]){
dp[++len] = p[i];
}
else{
dp[upper_bound(dp + 1, dp + len + 1, p[i]) - dp] = p[i];
}
}
return len;
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &p[i]);
p[i + n] = p[i];
}
int ans = 0;
for(int i = 1; i <= n; i++){
ans = max(ans, solve(i, i + n - 1));
}
printf("%d\n", n - ans);
return 0;
}