有nn
門功課,一些功課有先修課。每門功課都有學分。求選出m
m門功課能獲得的最大學分。
樹形dp+揹包。
很明顯,這道題肯定是設f[u
][j]
f[u]
[j]表示以u
u為根的子樹選出j
j門課程學習能獲得的最大學分。
那麼對於u
u的任意一棵子樹v
v,我們設它有s
s個結點,那麼我們就可以在這棵子樹中選擇任意k∈[
0∼s]
k∈[0
∼s]個結點來轉移。
那麼方程很明顯就是f[
u][j
]=ma
x(f[
u][j
],f[
u][j
−k−1
]+f[
v][k
])f[
u][j
]=ma
x(f[
u][j
],f[
u][j
−k−1
]+f[
v][k
])為什麼j−k
j−k之後還要減11呢?
因為要選擇u
u的子樹,那麼u
u是肯定得選的,所以在轉移的時候可以忽略掉這乙個結點。
那麼很明顯,最終答案就是f[0
][m]
f[0]
[m]。
#include
#include
#include
#define n 400
using
namespace std;
int n,m,f[n]
[n],head[n]
,tot;
struct edge
e[n]
;void
add(
int from,
int to,
int s)
intdp
(int x)
return sum;
}int
main()
dp(0)
;printf
("%d\n"
,f[0
][m]);
return0;
}
洛谷 P2014 選課(樹形揹包)
題面 洛谷 p2014 如題這種有依賴性的任務可以用一棵樹表示,因為乙個兒子要訪問到就必須先訪問到父親。然後,本來本題所有樹是森林 沒有共同祖先 但是題中的節點 0 其實就可以當做乙個lca,從節點 0 開始dp。狀態定義 dp x m x節點,選則m課,獲得的最大學分 決策時,模擬揹包,遍歷每乙個...
洛谷P2014 選課 樹形dp
給出n 300 n leq300 n 30 0個結點,每個結點都有乙個權值,然後一些結點必須只有選了前驅結點這個結點才可以被選。現在最多選m 300 m leq300 m 30 0個結點,求最大權值。實際上這個是乙個森林,但是通過設定乙個權值為0 00的虛點0 00,把所有的沒有前驅的點全部連到這個...
洛谷P2014 選課(樹形DP)
傳送門 難度提高 省選 該題是一道經典的樹形dp題目,基本就是樹形dp的板子題。注意點的解釋參考 為什麼最後兩行要單獨拿出來做呢?for int i s x i 0 i f x i 1 f x i p x 我們回到題面上,父親是兒子的先修課,所以沒有父親時,兒子再多也沒有用,揹包中處理的子樹是不帶根...