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個城堡所獲得的最多寶物的數量。
思路dp(i,j,k)表示第i個子樹,用前j子節點,最多攻略k個城堡所獲得的最大利潤。除了dfs列舉第i個子樹外,在第i個子樹內的狀態轉移類似不作優化的多重揹包,所以也可以用滾動陣列的思想,省掉j這一維。dfs加上三重迴圈的轉移,遞推式詳見**。最後要注意迭代的順序~
#include #include #include #include using namespace std;
const int maxn = 205;
int w[maxn];
int dp[maxn][maxn];
int n,m;
int nexte[maxn];
int g[maxn];
void addedge()
}int dfs(int x){
for(int i=m;i>=1;i--)
dp[x][i] = w[x];
int num = 1;
for(int e=g[x];e!=-1;e=nexte[e]){
num += dfs(e);
dfs(e);
for(int j = num; j >= 1; j--)
//k
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...
HDU 1561 樹形DP 揹包
題目鏈結 題目大意 從樹根開始取點。最多取m個點,問最大價值。解題思路 cost 1的樹形揹包。有個虛根0,取這個虛根也要cost,所以最後的結果是dp 0 m 1 本題是cost 1的特殊揹包問題,在兩個for迴圈上有乙個優化。for f 1.j.cost for 1.k.j cost 其中f為當...
HDU 1561(樹形dp 揹包問題)
題目 click 每個城堡被攻克,必須之前有乙個特定的城堡被攻克,才能攻占這個城堡。形成了一種子節點與父節點的關係,聯想到樹形dp取解決。走子節點必先走其父親節點,一次建樹,若無則父親節點為0 dp i j 表示以i為節點,取j個城堡寶藏獲得的最大值。include include include ...