原題鏈結
考察:樹形dp
思路:樹形揹包的時間複雜度是o(n3)
按劃分給子節點的體積來分配集合.思路與蘋果樹大體相同.關於幾個問題需要解釋下:
為什麼不和蘋果樹那題一樣在遍歷點的時候+w[u]. 答: k不一定能裝下,會使得揹包裡的價值多了.除此之外,f[u][j] = f[u][j-k]+f[vs][k],f[u][j-k]已經計入了w[u],在for迴圈裡加會重複.
為什麼要遍歷完後特地加for(int i=m;i>=v[u];i--) f[u][i] = f[u][i-v[u]]+w[u]; 答:加上原本的父結點
為什麼上面的迴圈是賦值而不是max. 答:dfs迴圈裡可能已經賦值了,但是我們不是必須放子節點,而是必須放根節點.
遍歷點外的for迴圈是否能是正序? 答:不能,這是01揹包,需要逆序推,否則f[i-v[u]]是已經被更新過的了.
內層迴圈為什麼從大到小遍歷:因為要用上乙個子節點的最優值.
1 #include 2 #include 3 #include 4 #include 5using
namespace
std;
6const
int n = 110;7
intv[n],w[n],n,m,root,idx,h[n];
8int
f[n][n];
9struct
roadroad[n];
12void add(int a,int
b)13
16void dfs(int
u)17
26for(int i=m;i>=v[u];i--) f[u][i] = f[u][i-v[u]]+w[u];
27for(int i=0;i0;28
}29intmain()
3040
dfs(root);
41 printf("
%d\n
",f[root][m]);
42return0;
43 }
AcWing 10 有依賴的揹包問題
有 n n n 個物品和乙個容量是 v v v 的揹包。物品之間具有依賴關係,且依賴關係組成一棵樹的形狀。如果選擇乙個物品,則必須選擇它的父節點。如下圖所示 如果選擇物品5,則必須選擇物品1和2。這是因為2是5的父節點,1是2的父節點。每件物品的編號是 i i i,體積是 v i vi vi,價值是...
Acwing 10 有依賴的揹包問題
題意 給定一棵樹的關係,每個節點都有對應的體積和價值,限制規則是選擇乙個節點是必須選擇它的父節點,給定總體積 m 問能獲得的最大的價值和是多少?include using namespace std int n,m,root,fa 110 v 110 w 110 dp 110 110 dp i j ...
題解 AcWing10 有依賴的揹包問題
題面 樹形 dp 的經典問題。我們設 dp 表示當前節點為 i 當前節點的子樹 包含當前節點 最多裝的體積是 j 的最大價值。我們遍歷節點的過程就相當於做了一遍分組揹包。注意遍歷完所有子節點後要更新一下狀態。include using namespace std const int maxn 103...