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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

POJ 4979 海贼王之伟大航路 【状压dp】【北大ACM/ICPC竞赛训练】

發布時間:2023/12/10 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ 4979 海贼王之伟大航路 【状压dp】【北大ACM/ICPC竞赛训练】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

該死的題讓我想起來艾斯之死...

?首先想到dp(i)代表從1到【i表示的這些島嶼】所花的最小時間,然后每次枚舉最后一個島嶼以此縮小范圍,但發現枚舉了最后一個島嶼后沒有辦法轉移,因為不知道倒數第二個島嶼是什么,隨著倒數第二個島嶼的不同,時間的增加也會不同,也就是不具備【無后效性】。

因此想到再加一個參數去約束當前問題的狀態,dp(i,j)代表1到【i代表的這些點】所需的最少時間,且這趟旅程的最后一個島嶼是j,這樣就可轉移了,每次枚舉倒數第二島嶼;答案就是dp( (1<<n) -1,n )

具體的位運算來判斷i有沒有包含k島嶼,自己拿筆推一下就行了

1 #include<iostream> 2 #define INF 1000000000 3 using namespace std; 4 5 int a[20][20],n; 6 int memo[66000][20]; 7 8 int dp(int i,int j){//dp[i,j]代表1到【i代表的這些點】所需的最少時間,且這趟旅程到的最后一個點在j 9 if( j==1 && i!=1 ) return memo[i][j] = INF; //只有當旅程只包含1的時候最后一個到的點才能是1 10 if(memo[i][j]!=INF) return memo[i][j]; 11 if( i == 1 && j==1 ) return memo[i][j]=0; 12 //枚舉倒數第二個島嶼在哪 13 for(int k=1;k<n;k++){ 14 if(k==j) continue;//倒數第二個島不能是倒數第一個島 15 if( i & 1<<(k-1) ) memo[i][j] = min( memo[i][j], dp(i- (1<<(j-1)),k)+a[k][j] ); 16 } 17 return memo[i][j]; 18 } 19 20 int main(){ 21 for(int i=1;i<66000;i++) 22 for(int j=1;j<20;j++) memo[i][j]=INF; 23 24 cin>>n; 25 for(int i=1;i<=n;i++) 26 for(int j=1;j<=n;j++) cin>>a[i][j]; 27 28 //固定起點為1和終點為N 29 cout<<dp( (1<<n)-1,n ); 30 return 0; 31 }

?

轉載于:https://www.cnblogs.com/ZhenghangHu/p/9368618.html

總結

以上是生活随笔為你收集整理的POJ 4979 海贼王之伟大航路 【状压dp】【北大ACM/ICPC竞赛训练】的全部內容,希望文章能夠幫你解決所遇到的問題。

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