狀態壓縮dp入門

2022-08-24 21:24:08 字數 3309 閱讀 6049

poj1321 

我們可以把棋盤的每一行看做是乙個狀態,如果某一列放置了棋子,那麼就標記為1,否則就標記為0.然後把它看成是乙個二進位制數,然後轉為10進製數,就可以當做陣列下標然後進行狀態轉移了

設dp[i][s] 為處理到第i行時,狀態為s的方法數

那麼我們列舉第i-1行的所有狀態s

dp[i][s] += dp[i-1][s]; //表示第i行不放置棋子的方法數

dp[i][s|(1<

1 #include 2 #include 

3char chess[9][9];int dp[11][1

<<8];4

intn,k;

5int

main()

617 dp[0][0] = 1;18

for(i=1; i<=n; ++i)

19for(s=0; s<(1

2027

///for(j=1; j

<=n; ++j)

28for(s=0; s

<(1<29

37 printf("

%d\n

",ans);38}

39return0;

40 }

poj3254 

本來這一題也想用上面那題的思路做,可是後來發現不行,因為上面那題一行只選擇乙個位置,而這題一行可以選擇多個位置。

那麼我們這題可以列舉多個位置,如果和上一行的狀態不衝突,那麼上一行的狀態就能轉移到這一行

1 #include 2 #include 34

int field[13];5

int situation[13];6

int dp[13][1

<<13];7

const

int mod = 100000000;8

bool isok(ints)9

1314

intmain()

15

2930

//dp[i][j] 表示處理完前i行,第j個狀態的方法數

31for(i=0; ii)

32if( !(situation[i] & field[0

]))33 dp[0][i] = 1;34

35for(i=1; ii)

36for(s=0; ss)

3745}46

for(i=0; ii)

47 ans = (ans + dp[n-1][i]) %mod;

48 printf("

%d\n

",ans);

4950}51

return0;

52 }

poj1185 

和上面那題差不多,只是當前行的狀態不止和上一行有關,還和上上一行有關,所以陣列要多開一維

奇怪的是為什麼用scanf("%c");g++ac,c++wa    用scanf("%s")g++和c++都wa

1/*2

分析:一行的狀態不能有 11(連續的兩個1) 也能有101(隔乙個空然後出現乙個1)

3dp[i][j][k] 表示第i行狀態為j第i-1行狀態為k時,最多有多少個炮兵擺放

4dp[i][j][k] = max(dp[i][j][k],dp[i-1][k][t]+num[j]);5*/

67 #include 8 #include

9int situation[11

];10

char matrix[111][11

];11

int map[111

];12

int num[111

];13

int dp[111][100][100

];14

bool isok(int

s)15

2021

int count(int

s)22

28 inline int max(const

int &a, const

int &b)

2932

intmain()

3345

46for(i=0; ii)

4756}57

for(i=0; ii)

58if(!(situation[i] & map[0

]))59 dp[0][i][0] =num[i];

60for(i=1; ii)

61for(j=0; jj)

6273}74

}75for(i=0; ii)

76for(j=0; jj)

77for(k=0; kk)

78 ans =max(ans,dp[i][j][k]);

79 printf("

%d\n

",ans);80}

8182

return0;

83 }

hdu3001 

平常的狀態壓縮,都是某個位置放(1)或者不放(0),所以可以直接用二進位制進行壓縮

但是這題,每個點可以走兩次,那麼就可以標記為0,1,2 所以要用三進製進行壓縮。

即用乙個陣列儲存每個狀態的三進製的每位

1 #include 2 #include 

3const

int inf = 1

<<30;4

int three[11],situation[59049][11],edge[11][11],dp[59049][11];5

void

init()620

}21}22 inline int min(const

int &a, const

int &b)

2326

intmain()

2747

for(i=0; i0;//

處於源點的距離為0

48//

因為走過某些城市可以是任意組合的,所以列舉這些狀態

49for(s=0; ss)

5063

}

64if(flag)//

走過所有的狀態

6569}70

if(ans ==inf)

71 printf("

-1\n");

72else

73 printf("

%d\n

",ans);74}

75return0;

76 }

狀態壓縮DP入門

中考前乙個學期都沒怎麼碰資訊,終於中考完了,第乙個來學習一下幾個dp。狀壓dp在提高組好像挺常考,而且我也一直不太會,便來學習一下。狀壓dp的基礎便是位運算。先來列幾個 與運算,二進位制下每一位進行如下運算 1 1 1 1 0 0 0 1 0 0 0 0,如 110 100 100,十進位制下即表示...

狀態壓縮DP入門題

在n n n 20 的方格棋盤上放置n 個車 可以攻擊所在行 列 求使它們不 能互相攻擊的方案總數。僅供和我一樣的菜鳥們參考 以n 4為例子解析原始碼 include include using namespace std int64 a 1100000 int main cout 前乙個狀態壓縮的...

狀態壓縮dp入門題目

題目大意是有m n的玉公尺地,但其中有些是不肥沃的,不能種植。用1來代表肥沃,0代表不肥沃。另外奶牛不喜歡挨著吃,也就是說要間隔著種植,求有幾種種植方式,並將計算結果對1e8取模。include include using namespace std int dp 12 1 12 dp i s 第i...