淺談狀態壓縮DP

淺談狀態壓縮DP

本篇隨筆簡單講解一下信息學奧林匹克競賽中的狀態壓縮動態規劃相關知識點。在算法競賽中,狀壓\(DP\)是很是常見的動規類型。不只如此,不只是狀壓\(DP\),狀壓仍是不少其餘題目的處理技巧。因此掌握狀壓、掌握狀壓DP是十分重要的。html

注:雖然本身寫的也是狀壓DP的講解。但仍是憑良心推薦機房大佬@littleseven的狀壓博客,講的真的是太詳細了。強烈推薦!算法

連接Link:數組

淺談狀壓DP函數

狀態壓縮的概念

來看一個問題。優化

相信你們都作過動態規劃的揹包問題,那麼咱們再來看一個跟揹包很像的一個問題:spa

如今對於一個大小爲\(V\)的揹包,有\(n\)個物品,每一個物品有一個價值和一個體積。請問:每種放置方法能達到的價值。設計

最暴力的方法是\(n\)重循環,每重循環只有兩次,一個是判斷,一個是不判斷,複雜度是\(O(2^n)\)的。htm

可是這種方法並非很是棒的,由於在編寫程序的時候,循環的層數是肯定的。可是\(n\)是一個變量,若是非要按這個方法寫的話,就會有一堆判斷(分別判斷\(n=1,n=2,n=3,...,n=maxn\))的狀況,麻煩得要死。blog

那怎麼辦呢?get

咱們能夠發現:對於每一種方法中的每種物品,都只有選或者不選兩種選擇。這就是一個決策過程,由於咱們要知道全部方式的價值,那咱們莫不如用一個二進制數表示這個狀態「選仍是不選」,二進制數對應的位就表示這個物品選仍是沒選,而後在二進制基礎上進行計算價值。

因此枚舉範圍就是\(0-2^n\),從一個都不選到全都選。

那麼咱們發現,本來須要開若干重循環和若干維數組的問題一會兒變成了用一個數組和一重循環就解決的問題了。

這個把狀態壓縮的過程就叫作狀態壓縮,在存儲狀態的基礎上進行枚舉轉移的動態規劃就叫作狀壓DP。

狀壓DP的前置知識

由於狀壓是在二進制的基礎上實現的一門DP算法,因此它必定會和位運算相關。事實上,全部狀壓\(DP\)都須要選手具備高深的位運算技巧,熟練運用位運算取出或設置每個狀態的判斷條件和轉移。

若是對位運算還不太懂的同窗,請參考這篇博客:

詳解位運算技巧

而且,咱們要對動態規劃的過程有一個直觀的認知。

有了這些知識,理解狀壓\(DP\)纔會更加流暢、順利。

狀壓DP的性質及特色

經過剛纔的例子(揹包),咱們會發現,狀壓對算法的時空複雜度並無多少的優化,也就是說,它的本質實際上是暴力枚舉。

由於是暴力枚舉,因此枚舉每一個狀態的時間複雜度是\(O(2^n)\),這是一個指數級別的時間複雜度。高中數學必修一的函數部分告訴咱們,指數是爆炸式增加的,也就是說若是不加優化,時間立刻就會炸掉。因此基於這個性質,通常來說狀態壓縮的題數據範圍不會超過\(20\),數量比較小。而基於這個性質,咱們設置狀態的時候也就挑這個最小的數來設置。

狀壓DP的解題思路

先來看一道狀壓基礎題(是洛谷藍題,可是由於狀壓都比較難,因此不用發怵)

USACO Corn Fields玉米田講解

題目大意:

給定一個\(N*M\)的矩陣,要在這個矩陣中種草,規定入股矩陣的值俄日1就能夠中,反之就不行。如今給出這個矩陣,請問它有多少種豬矩陣的方案。數據範圍:(\(1\le N,M\le 12\)

思路分析:

看見沒,數據範圍很是小,這樣的題往狀壓上想想。由於要統計方案數,因此咱們的狀態就設置成:\(dp[i][j]\)表示枚舉到第\(i\)行,第\(i\)行的狀態爲\(j\)時的方案數。那麼答案就是第\(n\)行的全部狀態方案數的和。

剛剛咱們已經說了,狀壓其實連優化枚舉都算不上,它就是方便了咱們寫枚舉的循環代碼,對複雜度並無多少貢獻。基於這個性質,咱們直接開始從頭枚舉,依次遞推便可。

但事實沒這麼簡單,由於咱們還須要判斷每一個狀態是否合法:若是不合法,那這個狀態就不能進行枚舉。

因此咱們再想辦法在轉移的時候判斷其到底合不合法便可。具體的實現請翻上面的題解。

總結:

狀壓\(DP\)算法的設計思路爲:(敲黑板!!)

設計狀態—>考慮轉移的先決條件—>想辦法維護這些條件—>進行轉移—>統計答案。

狀壓DP例題

USACO Corn Fields玉米田

SCOI互不侵犯

NOI炮兵陣地

以上爲基礎狀壓DP,如下爲狀壓DP進階

CQOI解鎖屏幕

SDOI學校食堂

相關文章
相關標籤/搜索