題目鏈結:
題目大意:樹中取點。每過一條邊有一定cost,且最後要回到起點。給定預算m,問最大價值。
解題思路:
首先要注意這題要回到起點,由於樹的特殊結構(每個結點只有乙個父親)也就是說,要回到開頭,
開銷是2倍。所以首先m/=2。
然後就是樹形揹包的求解,這題的cost在邊,所以for寫法變成如下:
for(m....j....0)
for(0....k....j-e.cost)
dp[i][j]=max(dp[i][j],dp[i][j-k-e.cost]+dp[t][k]);
for迴圈的主要變化是0的出現,也就是說某些點的開銷可以是0(在父親上算過了)。
所以初始化也要變成:for(int i=0;i<=m;i++) dp[root][i]=w[root];
dp方程的主要變化就是dp[i][j-k] -> dp[i][j-k-e.cost],這裡之所以要減去e.cost,是為了防止cost的重複計算。
不妨設k=j-e.cost,你就會發現在計算dp[i][0],這也是為什麼要推cost=0這個狀態。
#include "cstdio
"#include
"iostream
"#include
"cstring
"using
namespace
std;
#define maxn 300
struct
edge
e[maxn*2
];int
w[maxn],num[maxn],dp[maxn][maxn],head[maxn],tol;
intn,m,k,u,v,c;
void addedge(int u,int v,int
c)void dfs(int root,int
pre)
}int
main()
scanf(
"%d%d
",&k,&m);
m/=2
; dfs(k,k);
printf(
"%d\n
",dp[k][m]);
}}
2875311
neopenx
zoj3626
accepted
6360
c++ (g++ 4.4.5)
1174
2014-10-22 09:13:13
樹形揹包DP
include using namespace std const int n 310,m n 2 int h n ne m v m idx int w n int dp n n int n,m void add int a,int b void dfs int u for int j m j 0 ...
(選課)揹包類樹形dp
選課 學校實行學分制。每門的必修課都有固定的學分,同時還必須獲得相應的選修課程學分。學校開設了 n 門的選修課程,每個學生可選課程的數量 m 是給定的。學生選修了這 m 門課並考核通過就能獲得相應的學分。在選修課程中,有些課程可以直接選修,有些課程需要一定的基礎知識,必須在選了其他的一些課程的基礎上...
POJ 1155 TELE (樹形DP,樹形揹包)
題意 給定一棵樹,n個節點,其中有m個葉子表示的是使用者,其他點表示中轉器,每條邊都有權值,每個使用者i願意給的錢w i 問如果在不虧錢的情況下能為多少使用者轉播足球比賽?思路 其實就是要選出部分葉子節點,其花費 所選葉子權值 經過的所有邊權 每條邊只算1次花費 那麼對於每個節點,可以考慮在其子樹下...