互不侵犯 状压动归入门题
Code:
#include<cstdio> using namespace std; typedef long long ll; const int N=11; int v[1<<N],num[1<<N]; ll dp[N][1<<N][N*N]; int cnt,n,m; void init() { for(int i=0;i<(1<<n);++i) if((i&(i<<1))==0) { v[++cnt]=i; for(int j=0;(1<<j)<=i;++j) if((1<<j)&i)++num[cnt]; } } int ok(int i,int j) { if(i&j)return 0; if((i<<1)&j)return 0; if((j<<1)&i)return 0; return 1; } int main() { //freopen("in.txt","r",stdin); scanf("%d%d",&n,&m); init(); for(int i=1;i<=n;++i) { for(int j=1;j<=cnt&&v[j]<(1<<n);++j) { dp[i][j][num[j]]=1; if(i==1)continue; for(int k=1;k<=cnt&&v[k]<(1<<n);++k) if(ok(v[j],v[k])) for(int peo=num[j]+1;peo<=i*n&&peo<=m;++peo) { if(peo>num[j])dp[i][j][peo]+=dp[i-1][k][peo-num[j]]; } } } ll ans=0; for(int i=1;i<=cnt;++i) ans+=dp[n][i][m]; printf("%lld",ans); return 0; }
7