题解:CF1730F Almost Sorted
发现题目限制形如:最大的已经填入的数减小于这个数的最大的没有填的数
考虑按照
逆序对的贡献
时间复杂度
::::info[Code]
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
const int N=5e3+10,inf=1e9;
int n,k,p[N],q[N],sum[N][N],dp[N][1<<9];
inline pii trans(int s,int j){
int cnt=0;
s|=1<<(j-1);
while(s&1){
s>>=1;
++cnt;
}
return pii(cnt,s);
}
inline int getval(int pos,int s,int j){
int cnt=0;
for(int i=1;i<=k&&pos+i<=n;++i){
if(!((s>>(i-1))&1))continue;
cnt+=(q[pos+i]>q[pos+j]);
}
return cnt;
}
signed main(){
cin>>n>>k;
for(int i=1;i<=n;++i){
cin>>p[i];
q[p[i]]=i;
++sum[p[i]][i];
}
for(int i=1;i<=n;++i)
for(int j=n;j>=1;--j)
sum[i][j]+=sum[i-1][j]+sum[i][j+1]-sum[i-1][j+1];
++k;
int limit=1<<k;
for(int i=0;i<=n;++i)
for(int s=0;s<limit;++s)
dp[i][s]=inf;
dp[0][0]=0;
for(int i=0;i<n;++i)
for(int s=0;s<limit;++s)
for(int j=1;j<=k&&i+j<=n;++j){
if((s>>(j-1))&1)continue;
pii p=trans(s,j);
p.first+=i;
dp[p.first][p.second]=min(dp[p.first][p.second],dp[i][s]+sum[i][q[i+j]]+getval(i,s,j));
}
cout<<dp[n][0]<<"\n";
return 0;
}
::::