AcWing演算法提高課 有依賴的揹包問題
阿新 • • 發佈:2022-06-06
有依賴的揹包問題,節點有樹形結構的依賴。
可以遞迴計算。
遞迴的過程中,首先對節點的每個子樹,計算在不同體積下的最大價值,即dp[u][i]。
dp[u][i]代表在節點u的子樹中,選擇不超過體積i的物品所得到的最大價值。
然後對當前節點,將每個子節點的每個體積看做分組揹包問題中的物品求解。
在遞迴過程中,首先對全部子樹DFS(),
然後,首先考慮當前節點,由於當前節點必選,則將小於物品體積的dp[u][i]賦值為負無窮,其餘為w[u]。
然後遍歷所有子樹,遍歷當前節點所有體積,遍歷子樹節點的體積,進行dp。
注意分組揹包問題如果優化空間,則必須外層遍歷體積,內層遍歷當前組中的物品,保證小於當前體積的dp沒有被更新
10.有依賴的揹包問題
程式碼如下
#include<bits/stdc++.h> using namespace std; int v[110]; int w[110]; int p[110]; int V; vector<vector<int>> child(110); int dp[110][110]; void DFS(int index) { for (auto ch : child[index]) DFS(ch); memset(dp[index],-0x3f,sizeof(dp[index])); //dp[index][0]=0; forView Code(int j = V; j >= v[index]; j--) { dp[index][j] = w[index]; } for (auto ch : child[index]) { for (int j = V; j >= 0; j--) { for (int k = j; k >=0; k--) { dp[index][j] = max(dp[index][j], dp[index][j -k] + dp[ch][k]); } } } dp[index][0]=0; } int main() { int n; cin >> n >> V; int root; for (int i = 1; i <= n; i++) { cin >> v[i] >> w[i] >> p[i]; if (p[i] == -1) root = i; else child[p[i]].push_back(i); } DFS(root); //cout << dp[2][8] << endl; cout << dp[root][V] << endl; }