hdu 1561 依賴揹包

2021-12-29 16:39:24 字數 1412 閱讀 7540

題意:n座城堡,每個裡面都有寶物,要求在你可以攻占m個城堡得到的最多的寶物,但是如果要攻破乙個城堡,必須要攻破它依賴的那個城堡,例如,如果a依賴b,那麼如果想要攻破a就必須先攻破b。把每個城堡看作是物品,那麼這個物品的城堡數量是1,價值就是寶物了。

解題思路:根據題意知道這種關係會形成一顆多叉樹,根節點是0.從p=0開始,

1、遍歷所有p的孩子,遇到某個孩子還有孩子,就把該節點當作p,繼續1,直到遍歷完所有的節點,如果p的所有孩子都沒有孩子,那麼轉到2,存在有的孩子有孩子,轉到3;

2、對p的所有孩子進行01揹包,假設p的價值是vp,p共有n個孩子,然後對每個孩子進行01揹包(因為對於每個城堡只能取一次),那麼可以得到城堡數量從0到n對應的最大價值(0對應的肯定是0了),用dp[i]表示,i代表城堡數量,dp[i]代表價值,接著從i=0開始,都加上p的價值vp(因為所有的物品都依賴p),同時城堡的個數也加1;最後把得到的n+1個物品儲存到p點,這樣,這些物品就相當於分組揹包裡面的一組揹包了,儲存在castle裡面,然後接著步驟1的遍歷;

3、這個就很簡單了,由於已經遍歷過p所有孩子了,所以,只需要再從頭開始遍歷一遍所有孩子,如果遍歷的孩子還有孩子,那麼就把它的所有孩子當作是分組揹包處理,如果遍歷的孩子沒有孩子,那麼就當01揹包處理,最後會得到乙個城堡數量從0到m(也就是題目給的城堡數量的上限,以為不確定p的所有孩子的個數,所以就用最大的m)對應的最大價值,這個時候,如果p是0,那麼就輸出dp[m]就好了,如果不是,像2一樣,dp[i]代表的價值都加上p的價值,數量也加1,也儲存在castle裡面,繼續步驟1的遍歷;

具體**如下:

(提示:結構體s[i]代表城堡i的資訊:num表示城堡的數量,value代表價值,key是自身的序號,depend代表i依賴的城堡編號;list castle[i]記錄依賴i的城堡的資訊)

[cpp] 

#include  

#include  

#include  

#include  

using namespace std; 

#define n 205 

struct sss[n],one; 

list castle[n]; 

int dp[n],m; 

void fun(int n) 

memset(dp,0,sizeof(dp)); 

p=castle[n].begin(); 

while(p!=castle[n].end()) 

} } 

else 

p++; 

} castle[n].clear(); 

if(!n) 

cout<

else 

else 

} } 

}  int main() 

fun(0);  

} } 作者:jiang199235jiangjj

hdu1561 樹形揹包初探

problem description acboy很喜歡玩一種戰略遊戲,在乙個地圖上,有n座城堡,每座城堡都有一定的寶物,在每次遊戲中acboy允許攻克m個城堡並獲得裡面的寶物。但由於地理位置原因,有些城堡不能直接攻克,要攻克這些城堡必須先攻克其他某乙個特定的城堡。你能幫acboy算出要獲得盡量多的...

HDU 1561 樹形dp 揹包

分析 攻下一座城堡的前提是要先攻下它的前驅城堡,建立乙個以0為根結點的樹,他的權值為0 dp i,j 表示以i為根結點去j個的最大值。dp i,1 v i v i 為攻下i城堡獲得的寶藏 對與u結點取j 1個,可以轉化為以孩子i為根取k個 以自己為根取j 1 k個和自己取j 1個的最大值 為什麼是j...

hdu1561 樹上分組揹包

hdu1561 樹上揹包模板題 題意大概是給一棵樹,每個點有相應的權值,從樹根開始選取m個連通的點然後使得獲得的點權最大。我們假設dp u j 為以u點為根時,向下選取j個點獲得的最大權值。v為u的子節點,那麼可以看出其實當u點可以最多向下取p個點的時候,u點可以視為乙個容量為p的揹包,物品為dp ...