二進位制的很多應用離不開集合這個概念,我們都知道在計算機當中,所有資料都是以二進位制的形式儲存的。一般乙個int整形是4個位元組,也就是32位bit,我們通過這32位bit上0和1的組合可以表示多大21億個不同的數。如果我們把這32位bit看成是乙個集合,那麼每乙個數都應該對應集合的一種狀態,並且每個數的狀態都是不同的。
比如上圖當中,我們列舉了5個二進位制位,我們把其中兩個設定成了1,其餘的設定成了0。我們通過計算,可以得到6這個數字,那麼6也就代表了(00110)這個狀態。數字和狀態是一一對應的,因為每個整數轉化成二進位制都是唯一的。
也就是說乙個整數可以轉化成二進位制數,它可以代表某個集合的乙個狀態,這兩者一一對應。這一點非常重要,是後面一切推導的基礎。
整數的二進位制表示可以代表乙個二元集合的狀態,既然是狀態就可以轉移。在此基礎上,我們可以得出另乙個非常重要的結論——我們可以用整數的加減表示狀態之間的轉移。
我們還用剛才的例子來舉例,上面的圖當中我們列舉了5個二進位制位,假設我們用這5個二進位制位表示5個小球,這些小球的編號分別是0到4。這樣一來,剛才的6可以認為表示拿取了1號和2號兩個小球的狀態。
如果這個時候我們又拿取了3號小球,那麼集合的狀態會發生變化,我們用一張圖來表示:
上圖當中粉絲的筆表示決策,比如我們拿取了3號球就是乙個決策,在這個決策的影響下,集合的狀態發生了轉移。轉移之後的集合代表的數是14,它是由之前的集合6加上轉移帶來的變化,也就是
得到的。
剛好就代表拿取3號球這個決策,這樣我們就把整個過程串起來了。
總結一下,我們用二進位制的0和1表示乙個二元集合的狀態。可以簡單認為某個物品存在或者不存在的狀態。由於二進位制的0和1可以轉化成乙個int整數,也就是說我們用整數代表了乙個集合的狀態。這樣一來,我們可以用整數的加減計算來代表集合狀態的變化。
這也就是狀態壓縮的精髓,所謂的壓縮,其實就是將乙個集合壓縮成了乙個整數的意思,因為整數可以作為陣列的下標,這樣操作會方便我們的編碼。
最短hamilton路徑問題(也就是大名鼎鼎的旅行商問題)
給定一張 n
'>n
個點的帶權無向圖,點從 0~n-1 標號,求起點 0 到終點 n-1 的最短hamilton路徑。 hamilton路徑的定義是從 0 到 n-1 不重不漏地經過每個點恰好一次。
輸入格式
第一行輸入整數n
'>n
n。接下來n
'>n
n行每行n
'>n
n個整數,其中第i
'>i
i行第j
'>j
j個整數表示點i
'>i
i到j'>j
j的距離(記為a[i,j])。
對於任意的x,y
,z'>x,y,z
x,y,z,資料保證 a[x,x]=0,a[x,y]=a[y,x] 並且 a[x,y]+a[y,z]>=a[x,z]。
輸出格式
輸出乙個整數,表示最短hamilton路徑的長度。
資料範圍1≤
n≤20'>1≤n≤20
1≤n≤200≤
a[i,
j]≤10
7'>0≤a[i,j]≤107
0≤a[i,j]≤107
輸入樣例:
5
0 2 4 5 1
2 0 6 5 3
4 6 0 8 3
5 5 8 0 5
1 3 3 5 0
輸出樣例:18
1 #include2 #include3 #include45using
namespace
std;67
const
int n=20,m=1
<
8long
long
intdp[m][n];
9int
w[n][n];
10int
n;11
12int
main()
13
狀態壓縮DP 旅行商問題
題目描述 給定乙個n個頂點組成的帶權有向圖的距離矩陣d i j inf表示沒有邊 要求從頂點0出發,經過每個頂點恰好一次後再回到頂點0.問所經過的邊的總權重的最小值是多少?限制條件 題目解析 這個問題就是著名的旅行商問題 tsp 所有可能的路線有 n 1 種。這是乙個非常大的值,即使題中n已經很小了...
狀態壓縮動態規劃 旅行商問題
旅行商問題 n個點 n 16 的帶權有向圖d,求一條路徑,使得這條路經過每乙個點恰好一次。而且路徑上邊的權值和最小 或者最大 或者求一條具有這樣性質的迴路。狀態壓縮 將二進位制表示十進位制數n的點集,比方 10 0000000000001010 代表第1和3個點已經路過 18 00000000000...
從旅行商問題談狀態壓縮DP
乙個商品推銷員要去若干個城市推銷商品,該推銷員從乙個城市出發,需要經過所有城市後,回到出發地。應如何選擇行進路線,以使總的行程最短?請輸出最短行程。節點個數 n 滿足 2 leq n leq 20 路的長度小於 1000 例如這個旅行商問題,可能的路線一共有 n 1 種,如果純暴力試遍每一種方案,那...