《算法竞赛进阶指南》打卡-基本算法-AcWing 91. 最短Hamilton路径:位运算、状态压缩dp、dp
生活随笔
收集整理的這篇文章主要介紹了
《算法竞赛进阶指南》打卡-基本算法-AcWing 91. 最短Hamilton路径:位运算、状态压缩dp、dp
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
文章目錄
- 題目解答
- 題目鏈接
題目解答
分析:
狀態(tài)壓縮dp是用二進制數(shù)來表示狀態(tài)。
數(shù)據(jù)范圍n = 20, 那么狀態(tài)總量就是2202^{20}220個狀態(tài)。
可以按照以下思路去思考:
狀態(tài)表示
f[i][j]f[i][j]f[i][j]表示狀態(tài)為i,且停在點j的最短Hamilton路徑的長度。
狀態(tài)轉(zhuǎn)移:
state_k 是1個狀態(tài)的集合,其中不包括狀態(tài)j, f[state][j] = f[state_k][k] + weight[k][j]補充一個常用的技巧:
i >> j & 1這里的運算優(yōu)先級需要知道: 右移運算符(>>)的優(yōu)先級高于 位運算,所以這里先計算(i >> j),含義是i的二進制表示右移j位,也就是找到了i的第j位,然后與1(&1),含義是判斷這一位是否為1.(當然,這里的位,都是指二進制下的某一位)。
綜上,i >> j & 1表示 i的二進制表示中第j位是否為1.
同樣的道理,讀者可以分析一下下面這句代碼
i -(1 << j) >> k & 1提示: 減法優(yōu)先級 高于 右移(>>),右移(>>)優(yōu)先級高于 位運算與(&),上面這句話等同于
(i - (1 << j)) >> k & 1ac代碼
#include<bits/stdc++.h> using namespace std;const int N = 20, M = 1 << 20; // 狀態(tài) int n; // f[i][j] 表示狀態(tài)是i 的情況下,停在點j時的最短路徑是多少 int f[M][N], weight[N][N]; // 邊權(quán)int main(){cin >> n;for(int i = 0; i < n; i ++)for(int j = 0; j < n; j++)cin >> weight[i][j];memset(f, 0x3f, sizeof f);f[1][0] = 0; for(int i = 0; i< 1 << n; i ++){for(int j = 0; j < n; j ++){if( i >> j & 1) //判斷整數(shù)二進制表示的第j位是否是1for(int k = 0; k < n; k ++){// 看一下state_k 這個狀態(tài)// 減法優(yōu)先級 高于 右移>>,右移優(yōu)先級高于 位運算&if( i -(1 << j) >> k & 1)f[i][j] = min(f[i][j], f[i - (1<< j)][k] + weight[k][j]);}}}// 把所有點都遍歷過,并且停在了n-1這個點cout << f[(1 << n) -1][n -1] << endl; }題目鏈接
https://www.acwing.com/problem/content/93/
總結(jié)
以上是生活随笔為你收集整理的《算法竞赛进阶指南》打卡-基本算法-AcWing 91. 最短Hamilton路径:位运算、状态压缩dp、dp的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《算法竞赛进阶指南》打卡-基本算法-Ac
- 下一篇: 《算法竞赛进阶指南》打卡-基本算法-Ac