日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二进制状态压缩DP

發布時間:2023/12/4 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二进制状态压缩DP 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

描述
給定一張 n 個點的帶權無向圖,點從 0~n-1 標號,求起點 0 到終點 n-1 的最短Hamilton路徑。 Hamilton路徑的定義是從 0 到 n-1 不重不漏地經過每個點恰好一次。
輸入格式
第一行輸入整數n。

接下來n行每行n個整數,其中第i行第j個整數表示點i到j的距離(記為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路徑的長度。

數據范圍
1≤n≤20
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



一看到這道題目的時后我們一眼就覺得這是一道搜索題,但是我們仔細分析一下時間復雜度:
頭尾都是確定的,因此我們要對中間的(n - 2)個數進行全排列,大概就是(n - 2)!次方次排列,于是我們自然而然的就想到了用DP來絕決這個問題,但是用DP我們又該怎么樣來表示這之間的狀態呢。

每一個位置我們用0,1,來表示。0代表沒走過,1代表已近走過,
由此我們就有了狀態轉移方程。
DP[A][j] = min(DP[A][j], DP[B][k] + value[k][j])
其中AB,分別時兩個集合。B集合加上點 j 等于A集合。
每個狀態用其第幾位的二進制是0或者1來表示
我們有了下面的代碼

#include<iostream> #include<cstring> #include<algorithm> using namespace std; const int maxn = (1 << 20) + 10; int dp[maxn][22], value[22][22], n; int main() {cin >> n;for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)cin >> value[i][j];memset(dp, 0x3f, sizeof dp);dp[1][0] = 0;for(int i = 0; i < 1 << n; i++)for(int j = 0; j < n; j++)if(i >> j & 1)for(int k = 0; k < n; k++)if(i - (1 << j) >> k & 1)dp[i][j] = min(dp[i][j], dp[i - (1 << j)][k] + value[k][j]);cout << dp[(1 << n) - 1][n - 1] << endl;return 0; }

總結

以上是生活随笔為你收集整理的二进制状态压缩DP的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。