1. 程式人生 > 其它 >AcWing演算法提高課 有依賴的揹包問題

AcWing演算法提高課 有依賴的揹包問題

有依賴的揹包問題,節點有樹形結構的依賴。

可以遞迴計算。

遞迴的過程中,首先對節點的每個子樹,計算在不同體積下的最大價值,即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;
    for
(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; }
View Code