状态压缩dp入门
首先一次搜索,确定哪些状态能行,对应的国王数量是多少,然后再把放置到第多少行,状态是什么,国王数量是多少对应的方案数算出来,这就需要先确定状态,再通过状态转移求解。
dp[i][j][k]表示第I行,状态j,k个国王
并且去除掉相邻行的状态,再转移
最后把n行k个国王,所有的状态方案数总和算出来即可。
#include <bits/stdc++.h> using namespace std; #define ll long long ll dp[11][999][85]; int sta[999]; int sumk[999]; int n,k; int cnt=0; void dfs(int state,int cur,int num) { if(cur>=n) { sta[++cnt]=state; sumk[cnt]=num; return; } dfs(state|(1<<cur),cur+2,num+1); dfs(state,cur+1,num); } void dp_init() { for(int i=1;i<=cnt;i++) { dp[1][i][sumk[i]]=1; } for(int i=1;i<=n;i++){ for(int j=1;j<=cnt;j++){ for(int l=1;l<=cnt;l++){ if(sta[l]&sta[j]) continue; if((sta[l]<<1)&sta[j]) continue; if((sta[l]>>1)&sta[j]) continue; for(int p=sumk[l];p<=k;p++){ dp[i][l][p]+=dp[i-1][j][p-sumk[l]]; } } } } } int main() { scanf("%d%d",&n,&k); dfs(0,0,0); dp_init(); ll ans=0; for(int i=1;i<=cnt;i++) { ans+=dp[n][i][k]; } printf("%lld\n",ans); }