狀態壓縮是指用二進位制表示集合的方式對狀態進行壓縮,將其表示為乙個整數。
例如:用二進位制表示乙個集合的子集。
集合 s
=s = \
s=,那麼二進位制數(
01001)2
(01001)_2
(01001
)2,表示的就是s
ss的乙個子集s′=
s' = \
s′=,該子集可以用乙個十進位制數9
99來表示。
狀態壓縮dp其實是動態規劃類問題中一種特殊的狀態表示方式。若要表示的集合元素數量比較少(不超過20)時,想要儲存每個元素取或者不取時,可以借助位運算將狀態壓縮。需要借助狀態壓縮實現狀態表示的dp問題就稱為狀態壓縮dp。
例如取若干元素,如果選擇的話對應位置記為1,其餘位置記為0。例如一共有5個元素a,b
,c,d
,e
a,b,c,d,e
a,b,c,
d,e,分別用1,2
,4,8
,16
1,2,4,8,16
1,2,4,
8,16
表示這5個元素,則集合
\可以用(
00101)2
=3
(00101)_2 = 3
(00101
)2=
3來表示,而集合
\可以用(
11010)2
=26
(11010)_2=26
(11010
)2=
26表示。對於元素個數為n
nn的情況,其空間複雜度為(2n
)(2^n)
(2n)。n
nn個人在做傳遞物品的遊戲,編號為1
11-nnn。
即物品只能經過同乙個人一次,而且每次傳遞過程都有乙個代價;不同的人傳給不同的人的代價值之間沒有聯絡;
求當物品經過所有n
nn個人後,整個過程的總代價是多少。
輸入描述
第一行為n
nn,表示共有n
nn個人(2≤n
≤16
2≤n≤16
2≤n≤16
)。以下為n×n
n×nn×
n的矩陣,第i+1
i+1i+
1行、第j
jj列表示物品從編號為i
ii的人傳遞到編號為j
jj的人所花費的代價,特別的有第i+1
i+1i+
1行、第i
ii列為−1-1
−1(因為物品不能自己傳給自己),其他資料均為正整數(<
=1000
<=1000
<=1
000)。
輸出描述
乙個數,為最小的代價總和。
輸入樣例
3輸出樣例 在傳遞過程中,當前狀態可以表示為哪些人已經傳遞過物品、並且物品目前傳遞到哪個人手上。而已經傳遞過物品的人可以理解為從集合中已選取了哪些元素,因此可以使用狀態壓縮的方式,用二進位制數-1 2 4
3 -1 5
4 4 -1
01
來表示未傳遞和已傳遞的兩種狀態。
f[s][j]
表示當前傳遞狀態的集合為s
、並且傳遞到編號為j
的人手中時的最小的代價總和。
物品需要從上乙個人(不妨設編號為i
)傳遞過來,因此需要列舉所有可以傳遞到j
的人,取其中最小的代價總和。可以傳遞到j
,意味著編號為i
的人已經包含在集合s
中。
狀態轉移方程:f[s
][j]
=min]
[i]}
+w[i
][j]
f[s][j] = \min\][i]\} + w[i][j]
f[s][j
]=min][i
]}+w
[i][
j]其中:f[s
−][i
]f[s - \][i]
f[s−][
i]表示集合s
中不包含j
,即編號j
的人尚未被傳遞過物品。
題目中求最小值,因此首先將f
陣列初始化為無窮大。其次,從自己出發且傳遞給自己時,最小代價為0,即f[1 << i][i] = 0
。
狀態數2n×
n2^n \times n
2n×n
,轉移過程要迴圈n
nn次,所以時間複雜度為o(2
n×n2
)o(2^n\times n^2)
o(2n×n
2)
#include
#include
using
namespace std;
const
int n =
16, inf =
0x3f3f3f3f
;int w[n]
[n], f[
1<< n]
[n];
intmain()
}}}}
int res = inf;
//打擂台求出,傳遞過所有人後,且最後在i手上時的最小值
for(
int i =
0; i < n; i ++
) cout << res << endl;
return0;
}
動態規劃 狀態壓縮dp
if cnt 1 return false 用來判斷像01這種最後是0的情況 return true int main return 0 預處理所有狀態是否為合法狀態 include include include using namespace std typedef long long ll c...
動態規劃 dp狀態的壓縮
1312.讓字串成為回文串的最少插入次數 給你乙個字串 s 每一次操作你都可以在字串的任意位置插入任意字元。請你返回讓 s 成為回文串的 最少操作次數 回文串 是正讀和反讀都相同的字串。示例 1 輸入 s zzazz 輸出 0 解釋 字串 zzazz 已經是回文串了,所以不需要做任何插入操作。示例 ...
動態規劃之狀態壓縮
題目 是hdu 1074,題目大意是說 有幾門課的作業需要做,已知每門課作業的deadline和完成該作業需要花費的時間,求乙個作業的完成順序,使得最終的超時的天數最小。比如,現在如下輸入 computer 3 3 english 20 1 math 3 2 其中,第一列表示課程名,第二列表示dea...