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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【HDU - 1561】The more, The Better(树形背包,dp,依赖背包问题与空间优化,tricks)

發(fā)布時間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【HDU - 1561】The more, The Better(树形背包,dp,依赖背包问题与空间优化,tricks) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題干:

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

Input

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

Output

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

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

解題報告:

? ?建圖很方便,用零號頂點代表一個權(quán)值為0的城堡。然后跑的時候從零號頂點開始跑m+1個城堡就好了。比較容易可以看出來,這個問題是可以優(yōu)化空間和時間復(fù)雜度的。但是因為不卡內(nèi)存所以不需要做過多處理。(實際上,空間只用到了孩子和父親兩個的關(guān)系,所以可以01滾動數(shù)組優(yōu)化掉一維,對于空間,因為是求最大值問題,可以用線段樹來優(yōu)化第二維枚舉。)

這題屬于依賴背包,其實是三維的狀態(tài)。

這里主要是想說一下和01背包的區(qū)別,之所以01背包是N^2級別的復(fù)雜度,這個是N^3,就是因為對于每一個根節(jié)點更新狀態(tài)的時候,孩子節(jié)點不唯一,換句話說,01背包中,一個物品就代表選和不選兩個決策,他就只有一個物品;但是放到樹中,這一個孩子節(jié)點代表的是一棵子樹,所以要枚舉這子樹中選了多少沒選多少來更新狀態(tài), 所以多了一個量級的復(fù)雜度。

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair using namespace std; const int MAX = 200 + 5; vector<int> vv[MAX]; int val[MAX]; int n,m; int dp[MAX][MAX]; void dfs(int cur) {dp[cur][1] = val[cur];int up = vv[cur].size();for(int i = 0; i<up; i++) {int v = vv[cur][i];dfs(v);for(int j = m+1; j>=1; j--) {//j到2也可以ACfor(int k = 1; k<j; k++) {dp[cur][j] = max(dp[cur][j],dp[cur][j-k] + dp[v][k]);}}} } int main() {while(~scanf("%d%d",&n,&m) && n && m) {for(int i = 0; i<=n; i++) vv[i].clear();memset(dp,0,sizeof dp);for(int pre,i = 1; i<=n; i++) {scanf("%d%d",&pre,val+i);vv[pre].pb(i);}dfs(0);printf("%d\n",dp[0][m+1]);}return 0 ; }

?

總結(jié)

以上是生活随笔為你收集整理的【HDU - 1561】The more, The Better(树形背包,dp,依赖背包问题与空间优化,tricks)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。