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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

HDU1561:The more, The Better——题解

發布時間:2023/12/9 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU1561:The more, The Better——题解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://acm.hdu.edu.cn/showproblem.php?pid=1561

ACboy很喜歡玩一種戰略游戲,在一個地圖上,有N座城堡,每座城堡都有一定的寶物,在每次游戲中ACboy允許攻克M個城堡并獲得里面的寶物。但由于地理位置原因,有些城堡不能直接攻克,要攻克這些城堡必須先攻克其他某一個特定的城堡。你能幫ACboy算出要獲得盡量多的寶物應該攻克哪M個城堡嗎?

O(n*m^2)的復雜度相信大家已經都會了。

(代碼注釋區域的dfs)

這里介紹一種O(n*m)的算法,參考https://www.cnblogs.com/Patt/p/5642181.html與徐持衡的論文。

設dp[i][j]為取根節點到i節點路徑上的所有點,再從這條路徑的左邊上和i的子樹上取j體積的點的最大價值。最后答案為dp[0][m]。

(看起來這個定義沒法想,但是徐的論文給的方法是泛化物品合并……這個方法到現在還沒有看懂。)

對于所謂“路徑的左邊”可理解為dfs序比i小且不在這條路徑上的合法路徑。

(更饒了*2)

有一個看起來很妙的方程dp[u][j]=max(dp[u][j],dp[v][j-1]);

當然在這之前每個兒子我們都需要更新,dp[v][j]=dp[u][j]+w[v],然后把v遞歸跑一遍。

(思考為什么不是dp[u][j+1])

(卡了很久思索出了結果,實際很簡單,對dp[u][j]狀態它根本沒選擇v及其子樹的點,所以初始時dp[v][j]選擇的j個點正好是dp[u][j]的j個點)

#include<cstdio> #include<iostream> #include<vector> #include<queue> #include<cstring> #include<algorithm> #include<map> using namespace std; const int N=250; inline int read(){int X=0,w=0;char ch=0;while(!isdigit(ch)){w|=ch=='-';ch=getchar();}while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X; } struct node{int to,nxt; }e[N]; int cnt,head[N]; int n,m,w[N],dp[N][N]; inline void add(int u,int v){e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt; } /*void dfs(int u){for(int i=head[u];i;i=e[i].nxt){int v=e[i].to;dfs(v);for(int j=m;j>=2;j--){//保證無后效性for(int k=1;k<j;k++){dp[u][j]=max(dp[u][j],dp[u][k]+dp[v][j-k]);}}} }*/ void dfs(int u,int c){if(c<=0)return;for(int i=head[u];i;i=e[i].nxt){int v=e[i].to;for(int j=0;j<c;j++){dp[v][j]=dp[u][j]+w[v];}dfs(v,c-1);for(int j=1;j<=c;j++){dp[u][j]=max(dp[u][j],dp[v][j-1]);}} } int main(){while(scanf("%d%d",&n,&m)!=EOF&&n+m){n++;cnt=0;memset(head,0,sizeof(head));for(int i=1;i<n;i++){int u=read()+1,v=i+1;w[v]=read();add(u,v);}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){dp[i][j]=w[i];}}dfs(1,m);printf("%d\n",dp[1][m]);}return 0; }

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+歡迎訪問我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

轉載于:https://www.cnblogs.com/luyouqi233/p/8831338.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的HDU1561:The more, The Better——题解的全部內容,希望文章能夠幫你解決所遇到的問題。

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