BZOJ 1087状态压缩DP
状态压缩DP真心不会写,参考了别人的写法。
先预处理出合理状态,
我们用二进制表示可以放棋子的状态,DP[I][J][K]:表示现在处理到第I行,J:表示第I行的状态,K表示现在为止一共放的棋子数量。
#include<stdio.h> #include<iostream> #define N 1111 using namespace std; typedef long long ll; int num,n,m; ll dp[11][1<<11][90]; int hh[N],hnum[N]; int mp[1111][1111]; int check(int x,int y) { if (x&(y<<1)) return 0; if (x&(y>>1)) return 0; if (x&y) return 0; return 1; } int judge(int x) { if (x&(x<<1)) return 0; if (x&(x>>1)) return 0; return 1; } int getsum(int x) { int ans=0; while (x) { if (x&1) ans++; x>>=1; } return ans; } void pre() { num=0; for (int i=0;i<(1<<n);i++) if (judge(i)) { hh[++num]=i; hnum[num]=getsum(i); } for (int i=1;i<=num;i++) for (int j=1;j<=num;j++) if (check(hh[i],hh[j])) mp[i][j]=mp[j][i]=1; } int main() { cin>>n>>m; pre(); dp[0][1][0]=1; for (int i=0;i<n;i++) for (int j=1;j<=num;j++) for (int k=0;k<=m;k++) if (dp[i][j][k]) for (int p=1;p<=num;p++) if (mp[j][p]&&k+hnum[p]<=m) dp[i+1][p][k+hnum[p]]+=dp[i][j][k]; ll ans=0; for (int i=1;i<=num;i++) ans+=dp[n][i][m]; cout<<ans<<endl; return 0; }
随性Code