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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

The more, The Better(HDU-1561)

發布時間:2025/3/17 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 The more, The Better(HDU-1561) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Problem Description

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

Input

每個測試實例首先包括2個整數,N,M.(1 <= M <= N <= 200);在接下來的N行里,每行包括2個整數,a,b. 在第 i 行,a 代表要攻克第 i 個城堡必須先攻克第 a 個城堡,如果 a = 0 則代表可以直接攻克第 i 個城堡。b 代表第 i 個城堡的寶物數量, b >= 0。當N = 0, M = 0輸入結束。

Output

對于每個測試實例,輸出一個整數,代表ACboy攻克M個城堡所獲得的最多寶物的數量。

Sample Input

3 2
0 1
0 2
0 3
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
0 0

Sample Output

5
13

思路:樹形 DP

設 dp[i][j] 為以第 i 號為根取 j 個的最大值,顯然,當以 i 號結點為根取 1 個時,其值為第 i 號城堡本省的價值,即?dp[i][1]=w[i]

以樣例 2 為例,可以建得如下的一個圖

選擇一棵樹,從根節點向子節點直接進行動態規劃,由于對任意結點 i 有 dp[i][1]=w[i],那么如果要求 dp[i][j] 的話,就要對其子樹達到最優后再解決當前的問題,即有:dp[i][j]=max{ dp[i][j],dp[i][k]+dp[子節點][i-k] },其中 k 代表取k個點

得到狀態轉移方程后,可以發現,圖是一個森林,這個時候,就需要加一個虛擬的根節點,將其權值設為 0,從其開始進行狀態轉移,這樣一來,就要求包括其自身在內的 m+1 個點的最優值

Source Program

#include<iostream> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<utility> #include<stack> #include<queue> #include<vector> #include<set> #include<map> #define PI acos(-1.0) #define E 1e-6 #define MOD 1000000007 #define INF 0x3f3f3f3f #define N 1001 #define LL long long using namespace std; struct Edge{int next;int to; }edge[N]; int head[N],cnt; int n,m; int dp[N][N];//以i為根攻破j個城堡的最大值 bool vis[N]; void addEdge(int next,int to){edge[cnt].to=to;edge[cnt].next=head[next];head[next]=cnt++; } int dfs(int x){//以x為根結點向下搜索vis[x]=true;for(int i=head[x];i!=-1;i=edge[i].next){int y=edge[i].to;//與x鄰接的點if(!vis[y])dfs(y);for(int j=m+1;j>=2;j--)//除虛擬的根結點外,枚舉要攻破的城堡個數for(int k=1;k<j;k++)//取k個點if(dp[y][j-k]!=-1&&dp[x][k]!=-1)dp[x][j]=max(dp[x][j],dp[x][k]+dp[y][j-k]);} } int main(){while(scanf("%d%d",&n,&m)!=EOF&&(n+m)){memset(dp,-1,sizeof(dp));memset(head,-1,sizeof((head)));memset(vis,false,sizeof(vis));cnt=0;//由于圖可能為一森林,因此加一虛擬根節點,使其值為0for(int i=0;i<=n;i++)dp[i][0]=0;dp[0][1]=0;for(int i=1;i<=n;i++){int x,y;scanf("%d%d",&x,&y);addEdge(x,i);dp[i][1]=y;//以第i個點為根攻破1的城堡的值一定是這個城堡自身的值}dfs(0);//以虛擬結點為根節點向下搜索printf("%d\n",dp[0][m+1]);}return 0; }

?

總結

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

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