狀壓dp分兩大類,一類是集合式,另一類就是棋盤式(即基於連通性)。我們先看以下三個例題。其中,集合式狀壓dp難度相較後者略大,形式複雜多變。而棋盤式狀壓dp的題目樣式都相差不多,解法也都殊途同歸,因此將這一類題進行總結,不難歸結出一套解題模板。
題目鏈結
狀態表示:f[i,j,s]表示已經在前i行放了j個國王,且第i行的狀態為s的方案數。#include #include #include #include using namespace std;狀態轉移:考慮第i-1行所有合法狀態x,則f[i,j,s]=∑f[i-1,j-count(s),x],其中count(s)表示s中國王的個數。
演算法流程:
1.考慮將一行的狀態進行壓縮,然後預處理所有合法狀態。
2.列舉所有合法狀態,對於每一種合法狀態,處理該狀態可由哪些狀態轉移過來。
3.迴圈列舉dp狀態,進行狀態轉移。
typedef long long ll;
const int n=12;
int stt[1<>i&1 && state>>i+1&1)return false;
return true;
}int count(int state)
int main()
int main()
,其中count(b)表示狀態b中放置的個數。
演算法流程:
1.預處理所有合法狀態。
2.列舉dp狀態,考慮當前狀態與地圖限制是否矛盾,然後列舉dp轉移,考慮狀態之間的限制。
考慮到空間限制,需要用滾動陣列優化。
#include #include #include #include using namespace std;
const int n=110,m=11;
int stt[1<>i&1) && (state>>i+1&1 || state>>i+2&1))return false;
return true;
}int count(int state)
int main()
{ scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{static char ch[m];
scanf("%s",ch);
for(int j=0;j常規步驟:
1.預處理所有合法狀態。
2.若空間允許,則對於每乙個合法狀態,預處理能夠轉移到其的所有合法狀態的集合。
3.迴圈dp狀態,考慮地圖本身的限制,若無矛盾,則迴圈dp轉移。
狀壓dp之棋盤覆蓋
1.poj2411 題目大意 用2 1的骨牌覆蓋滿乙個n m的矩陣,求方案數。n,m 11 題目分析 由於n和m都很小,可以想到狀態壓縮dp。如果我們f i j 表示某i行的狀態j,在狀態j中,1表示已經覆蓋,0表示沒有覆蓋,那麼有三種情況 1.不放 2.橫著放 3.豎著放。用dfs來尋找每行和它上...
狀壓DP初探 總結
2018過農曆新年這幾天,學了一下狀態壓縮動態規劃,現在先總結一下。狀態壓縮其實是一種並沒有改變dp本質的優化方法,階段還是要照分,狀態還是老樣子,決策依舊要做,轉移方程還是得列,最優還是最優,無後還是無後,所以它比較好理解。狀壓,顧名思義就是要將一些狀壓想辦法壓縮起來 可以壓,也可以刪 其中這些狀...
狀壓DP的總結
狀壓dp的標誌 資料小 通過題目所給出的條件以後得到的特徵集合小 一 cf259div2 d 題目大意 保證b i 中每個數互質,給出a i 然後求1 n的abs a i b i 最小。a i 30 思路 首先得到b i 必然小於60。這個很重要,因為我們列舉的b的集合就是60.首先當b如果都取1,...