http://www.lydsy.com/JudgeOnline/problem.php?id=1087.
装压dp,dp(i,j,k)表示前i行放了了j king,第i行的状态时k
转移枚举上一行状态转移
复杂度$O(n^32^n)$
#include<cstdio> #include<iostream> using namespace std; const int maxn = 11; inline int read() { int x=0; char c=getchar() ; while(c<'0'||c>'9'); while(c<='9'&&c>='0') { x=x*10+c-'0';c=getchar(); } return x; } int k,n; long long dp[maxn][83][1<<maxn]; int num[1<<maxn]; int main() { n=read();k=read(); dp[0][0][0]=1; for(int kk,i=1;i<1<<n;++i) { kk=i; while(kk) { if(kk&1)num[i]++;kk>>=1; } } for(int i=1;i<=n;++i) { for(int j=0;j<=k;++j) { for(int k=0;k<(1<<n);++k) { if(k&(k>>1)||k&(k<<1))continue; if(num[k]>j)continue; for(int p=0;p<(1<<n);++p) { if(p&(p<<1)||p&(p>>1)||(p<<1)&k||(p>>1)&k||p&k)continue; dp[i][j][k]+=dp[i-1][j-num[k]][p]; } } } } long long ans=0; for(int i=0;i<(1<<n);++i) { ans+=dp[n][k][i]; } printf("%lld ",ans); return 0; }