題解 poj3254 狀壓DP

2021-08-22 19:43:32 字數 1359 閱讀 1113

題目鏈結

思路摘抄自大佬部落格

狀態可由二進位制表示,只需將每種狀態轉化為相應的十進位制數,即可只用乙個數字,就能表示某一種狀態

以dp[i][state(j)]來表示對於前i行,第i行採用第j種狀態時可以得到的可行方案總數!

例如:回頭看樣例資料,dp[2][1]即代表第二行使用第2中狀態(0 1 0)時可得的方案數,即為4;

那麼,可得出狀態轉移方程為:

dp[i][state(j)]=dp[i-1][state(k1)]+dp[i-1][state(k2)]+……+dp[i-1][state(kn)](kn即為上一行可行狀態的編號,上一行共有n種可行狀態)

最終ans=dp[m][state(k1)]+dp[m][state(k2)]+……+dp[m][state(kn)]; (kn即為最後一行(第m行)可行狀態的編號)

//狀壓dp

#include

#include

using

namespace

std;

#define mod (int)1e8

int m,n,top=0;

//top表示每行最多的狀態數

int state[600],num[110];

//state存放每行所有的可行狀態

int dp[20][600];

//dp[i][j]:對於前i行資料,每行有前j種可能狀態時的解

int cur[20];

//cur[i]表示第i行整行的情況

inline

bool ok(int x)//判斷x狀態是否可行

void init()//遍歷所有可能的狀態

inline

bool fit(int x,int k)//判斷狀態x與第k行的實際狀態的逆是否有重合

int main()

}for(int i=1;i<=top;i++)

if(fit(state[i],1))//判斷所有可能狀態與第一行的實際狀態的逆是否有重合

dp[1][i]=1;

//狀態轉移過程中,dp[i][k]=∑dp[i-1][j](j為符合條件的所有狀態)

for(int i=2;i<=m;i++)//i索引第2行到第m行

for(int k=1;k<=top;k++)//該迴圈針對所有可能的狀態,找出一組與i第i行相符的state[k]

}int ans=0;

for(int i=1;i<=top;i++)//累加最後一行所有可能狀態的值

ans=(ans+dp[m][i])%mod;

printf("%d\n",ans);

}return

0;}

poj3254 基礎狀壓dp

第二個狀壓dp 做過的第乙個也是放牛問題,兩頭牛不能相鄰 這個題多了乙個限制,就是有些位置不能放牛 於是先與處理一下每一行所有不能放牛的狀態,處理的過程直接對每乙個不能放牛的狀態或以下 ac include include include include include include using ...

POJ 3254 (狀態壓縮DP)

思路 狀態壓縮dp,用二進位制位的1表示放了,0表示沒有放。設dp i j 表示第i行狀態為j時,前i行的方案數,狀態轉移方程就是 dp i j dp i 1 k j與k這兩個狀態不衝突。最後答案就是dp n 1.top 之和。include include include include incl...

poj3254 狀態壓縮DP

全程精講 農夫有一塊地,被劃分為m行n列大小相等的格仔,其中一些格仔是可以放牧的 用1標記 農夫可以在這些格仔裡放牛,其他格仔則不能放牛 用0標記 並且要求不可以使相鄰格仔都有牛。求方案數 include include using namespace std define mod 10000000...