BZOJ 1087状态压缩DP
生活随笔
收集整理的這篇文章主要介紹了
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; }
轉載于:https://www.cnblogs.com/forgot93/p/3842783.html
總結
以上是生活随笔為你收集整理的BZOJ 1087状态压缩DP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ajax异步通讯 遮罩滚动栏,防止并发及
- 下一篇: 黑马程序员之单例模式学习