好久沒更新部落格了~
最近學了一下狀壓dp的內容,感覺對狀態壓縮有一點了解,不過有時候做題的時候總感覺有些吃力。今天做了2道tsp的題,雖然知道套路,但是對細節處理做的還是很不好,主要原因就是因為我對演算法的認識還不夠深刻吧,有時候碰到沒有遇到過的題型的時候,總想著去查資料,沒有深入思考過。其實費老強調過這一點。不要題海戰術,要以一擋十。以後要改掉這個壞習慣。
言歸正傳。下面來總結一下,最近學狀壓dp的收穫。
狀態壓縮就是將乙個狀態,用2進製的方法,壓縮成乙個數。
1.解法需要儲存一定的狀態資料(表示一種狀態的乙個資料值),每個狀態資料通常情況下是可以通過2進製來表示的。這就要求狀態資料的每個單元只有兩種狀態,比如說棋盤上的格仔,放棋子或者不放,或者是硬幣的正反兩面。這樣用0或者1來表示狀態資料的每個單元,而整個狀態資料就是乙個一串0和1組成的二進位制數。
2.解法需要將狀態資料實現為乙個基本資料型別,比如int,long等等,即所謂的狀態壓縮。狀態壓縮的目的一方面是縮小了資料儲存的空間,另一方面是在狀態對比和狀態整體處理時能夠提高效率。這樣就要求狀態資料中的單元個數不能太大,比如用int來表示乙個狀態的時候,狀態的單元個數不能超過32(32位的機器)。
位操作實現技巧:
如果要獲得第i位的資料,判斷((data&(0x << i))==0),若真,為0,假,為1;
如果要設定第i位為1,data=(data|(0x1<< i));
如果要設定第i位為0,data=(data&(~(0x1<< i)));
如果要將第i位取反,data=(data^(0x1<< i);
如果要取出乙個數的最後乙個1(lowbit):(data&(-data))
舉個例子來說。
hdu 1565 方格取數
大致題意就是:給你乙個n*n的格仔的棋盤,每個格仔裡面有乙個非負數。
從中取出若干個數,所取的數所在的2個格仔不能相鄰,並且取出的數的和最大。
這個題就是很典型的乙個狀態壓縮題。
對於每一行來說,每個數都有兩種選擇,選或者不選。那麼我們就可以用0代表不選,1代表選。
比如說:10101就代表選第1,3,5個數。並且10101=21。
所以21這乙個十進位制的數就可以表示第一行的這個狀態。
這個題的解題思路就是:
1.先列舉所有狀態(從0到1<< n)找出不含相鄰1的狀態,那麼這就是滿足每一行不相鄰的所有合法狀態。
2.特殊處理第1行的狀態。上一步找到的合法狀態都可以作為是第1行的狀態。
3.列舉後面的行。後面的行要滿足2個條件。一就是沒有相鄰的1。二是和上一行的1不衝突。找到合法的狀態,利用dp求出最大值就好了。
這個是最簡單的套路。後面很多類似的題,都是這個套路。
狀壓dp的大致思想就是這樣。
剩下內容寫在題解裡面吧~
狀態壓縮dp小結
訓練了近乙個星期的狀態壓縮dp,對狀態壓縮有了初步的了解。1核心 對問題的狀態進行壓縮,大部分是將狀態轉化為二進位制的形式,然後進行dp。2使用條件 情況數不是很多,否則會超時。3常見壓縮內容 1地圖 的選擇1為選0為不選,即可將一行的狀態表示出來,然後進行dp得優解。2安排任務 安排任務的先後 3...
狀態壓縮DP
首先,我們以一道狀壓經典題tsp來引入。tsp問題 一張圖上有n個點,給定相應的鄰接矩陣,需要求出從0號節點出發,經過且只經過每個頂點一次,最後仍回到0號節點的最小邊權。思路 假設現在已訪問過的頂點集合 起點0當作還未訪問過的頂點 為s,當前所在頂點為v,用dp s v 表示從v出發訪問剩餘的所有頂...
狀態壓縮DP
theme 給定乙個n m的玉公尺田,1 n,m 12。值為0表示不能在該塊種草,為1表示可以。現在要在其上中若干草地,要求任意草地間不相鄰 沒有公共邊 問不考慮草地個數的情況下,有多少種種植的方案?solution 用dp。又範圍很小,所以考慮狀態壓縮dp,另dp i j 表示從前i行種植,最後一...