题解:
点击打开链接
按照插入数的大小排序,
然后依次进行dp。
用一个状态表示n个数是否被选了
10110 就是表示第1、3、4个位置都选了
那么如果此时这个数该填到5这个位置,那么必定会造成一个逆序(因为下一个数会填到2,下一个数必定比这个数大)
也就是转移的时候看插入位置前有多少个0,进行转移
代码:
#include<bits/stdc++.h> using namespace std; int n,m,i,x,ii,j,sum,f[2000001]; int main(){ scanf("%d%d",&n,&m); for(i=1;i<(1<<n);i++)f[i]=-500000000; for(ii=1;ii<=m;ii++){ scanf("%d",&x);x--; for(i=0;i<(1<<n);i++){ if(!(i>>x&1)&&f[i]!=-500000000){ sum=0; for(j=x+1;j<=n;j++)sum+=i>>j&1; f[i|(1<<x)]=max(f[i|(1<<x)],f[i]+sum); } } } printf("%d",f[(1<<n)-1]); }