《更新提示》
《第一次更新》狀壓dp入門
《正文》
給定一張 n(n≤20) 個點的帶權無向圖,點從 0~n-1 標號,求起點 0 到終點 n-1 的最短hamilton路徑。 hamilton路徑的定義是從 0 到 n-1 不重不漏地經過每個點恰好一次。
第一行乙個整數n。 接下來n行每行n個整數,其中第i行第j個整數表示點i到j的距離(乙個不超過10^7的正整數,記為a[i,j])。 對於任意的x,y,z,資料保證 a[x,x]=0,a[x,y]=a[y,x] 並且 a[x,y]+a[y,z]>=a[x,z]。
乙個整數,表示最短hamilton路徑的長度。
4
0 2 1 3
2 0 2 1
1 2 0 1
3 1 1 0
4
很容易想到的樸素解法是列舉全排列,時間複雜度\(o(n*!n)\),顯然是會\(tle\)的。注意到\(n<20\),我們考慮狀態壓縮\(dp\)。設\(f[i][s]\)代表當前遍歷狀態為\(s\),到了第\(i\)個點的最短長度。如何理解遍歷狀態\(s\)呢?我們把它當做乙個二進位制的\(01\)串,從右數第i位為如果為\(0\),就說明節點i沒有被遍歷到過,如果第\(i\)位為\(1\),則說明節點i被遍歷到過了。我們將整個圖的遍歷狀態記為乙個二進位制數,這就是狀態壓縮。
那麼我們考慮如何\(dp\)。我們將編號記為從\(1\)開始的,那麼初始狀態就是\(f[1][1]=0\)。
這裡我們需要先理解狀態的查詢和賦值操作:
1.那麼我們就可以得到狀態轉移方程了:$$f[j][s|(1<<(j-1))]=\min$$s&(1<<(i-1))
代表取出狀態s的(從右往左)第i位2.
s|(1<<(i-1))
代表將狀態s的(從右往左)第i位賦值為1
需要滿足節點\(j\)未訪問,節點\(i\)已經訪問過了。
狀態的初值一開始均為正無窮,列舉\(s,i,j\)即可轉移,時間複雜度\(o(n^2*2^n)\),目標狀態為\(f[n][(1<。
\(code:\)
#includeusing namespace std;
const int n=20;
int n,dis[n+5][n+5],f[n+5][(1<
《後記》
最短Hamilton路徑 upc 狀壓DP
題目描述 給定一張 n n 20 個點的帶權無向圖,點從 0 n 1 標號,求起點 0 到終點 n 1 的最短hamilton路徑。hamilton路徑的定義是從 0 到 n 1 不重不漏地經過每個點恰好一次。輸入第一行乙個整數n。接下來n行每行n個整數,其中第i行第j個整數表示點i到j的距離 乙個...
最短Hamilton路徑與狀壓DP
最短hamilton路徑的意思是遍歷一張圖,每個節點不重不漏的走過一次 不能多 這樣一種走法的最短路徑。這樣的一種問題可以通過狀態壓縮動態規劃來實現,其核心思想是以二進位制形式列舉各個點是否被走過的狀態,通過這些子狀態推得答案。如何設計這個方案呢?可以設dp陣列第一維指代當前點的經歷情況 這是二進位...
0103 最短Hamilton路徑 狀壓DP
描述 給定一張 n n 20 個點的帶權無向圖,點從 0 n 1 標號,求起點 0 到終點 n 1 的最短hamilton路徑。hamilton路徑的定義是從 0 到 n 1 不重不漏地經過每個點恰好一次。輸入格式 第一行乙個整數n。接下來n行每行n個整數,其中第i行第j個整數表示點i到j的距離 乙...