狀態壓縮的基本操作

2022-05-15 13:05:58 字數 1647 閱讀 3314

數量規模不超過20時 要儲存每個狀態取或不取的狀態時可以用狀態壓縮。

所謂狀態壓縮,就是用二進位制數表示集合 用1代表有該元素,0代表沒有該元素

=37  表示集合中有第1,3,6個元素。  用狀壓dp儲存狀態消耗的空間是2^n

例題1:

有乙個n*m的矩陣 其中有的格仔可以選,有的不能選, 且不能選中相鄰的格仔

問: 最多能選定多少個格仔?

例如下面的格仔, 可選的標為1,不可選的標為0

選擇的方案是

共3個可選位置

這一行的選擇情況可以用二進位制表示,設這行選了now , 這行的限定條件是 lim , 上一行選了 pre 

對於條件1: lim | now == lim

條件2: now&(now>>1) ==0

條件3: now&pre==0

完整**

1

const

int max_n = 20;2

const

int max_m = 20;3

int state[max_n + 1];4

int dp[max_n + 1][1

<

bool not_intersect(int now, int

prev) 910

bool fit(int now, int

flag)

13bool ok(int

x) 17

int count(int

now)

23return

s;24}25

26int

main() 36}

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

42int cnt = count(j); //

統計當前行一共選了多少個格仔

43for (int k = 0; k < (1

<< m); ++k) 47}

48}49}

50int ans = 0; //

儲存最終答案

51for (int i = 0; i < (1

<< m); ++i)

54 cout << ans <

55return0;

56 }

view code

統計二進位制數中1的數目

int count(int

x)

return

num;

}

例子2:  消除回文串

給定乙個字串s  可以從中消除回文串, 回文串不必連續,問最少多少次可以消除整個串

狀態d[ i ] 表示消除字串i 需要的最少步數。

狀態轉移: if( i串不是回文串)  d[ i ] = d [ j ] + d [ j^i];  else  d[ i ] = 1;   // j  是i串的子集 ,  j^i 是  j的補集

for (int t = 1; t < (1

<< n); t++)

}}printf(

"%d\n

", dp[(1

<< n) - 1]); //

輸出最終答案

//列舉子集  for(int i = t ; i ; i = (i - 1) & t ) 

linux基本操作 壓縮命令

1.gzip gzip,壓縮時不保留原檔案 gzip,不能壓縮目錄 對於大檔案 壓縮比還是比較大的 壓縮前 451820 apr 13 22 31 file kuerl 壓縮後 97342 apr 13 22 31 file kuerl.gz 2 bzip2適用於一些內容和資料較大的檔案進行壓縮 3...

執行緒的狀態轉換以及基本操作

public class createthreaddemo thread.start 2.實現runable介面 thread thread1 newthread new runnable thread1.start 3.實現callable介面 executorservice service ex...

狀態壓縮DP

首先,我們以一道狀壓經典題tsp來引入。tsp問題 一張圖上有n個點,給定相應的鄰接矩陣,需要求出從0號節點出發,經過且只經過每個頂點一次,最後仍回到0號節點的最小邊權。思路 假設現在已訪問過的頂點集合 起點0當作還未訪問過的頂點 為s,當前所在頂點為v,用dp s v 表示從v出發訪問剩餘的所有頂...