可以发现,一个值只需要移动一次即可。
考虑让一些值固定不动,并让其他值移动一次。可以证明,这是最优方案。
考虑任意可行方案,若没有数操作次数为 \(0\),显然不优,否则保持为 \(0\) 的值不动,可以让其它位置只移一次,显然不劣。
考虑到不动的数最后在序列中肯定是位置连续的,所以必须形如 \(a,a+1,a+2,\cdots\)。
即寻找最长值域连续上升子序列。
DP 即可。
#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
char buf[1<<14],*p1=buf,*p2=buf;
#define GetC() ((p1==p2)&&(p2=(p1=buf)+fread(buf,1,1<<14,stdin),p1==p2)?EOF:*p1++)
struct Ios{}io;
template <typename _tp>
Ios &operator >>(Ios &in,_tp &x){
x=0;int w=0;char c=GetC();
for(;!isdigit(c);w|=c=='-',c=GetC());
for(;isdigit(c);x=x*10+(c^'0'),c=GetC());
if(w) x=-x;
return in;
}
const int N=2e5+5;
int dp[N];
int main(){
int n;io>>n;
for(int i=1;i<=n;++i){
int x;io>>x;
dp[x]=1;
dp[x]+=dp[x-1];
}
int ans=0;
for(int i=1;i<=n;++i) ans=max(ans,dp[i]);
printf("%d\n",n-ans);
return 0;
}
标签:int,GetC,Ios,char,AGC024B,Backfront,include,dp
From: https://www.cnblogs.com/pref-ctrl27/p/17024246.html