題目鏈結
思路摘抄自大佬部落格
狀態可由二進位制表示,只需將每種狀態轉化為相應的十進位制數,即可只用乙個數字,就能表示某一種狀態
以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...