AcWing 10. 有依賴的揹包問題(圖解版)
阿新 • • 發佈:2021-12-22
一、思路分析
二、實現程式碼
#include <bits/stdc++.h> using namespace std; const int N = 110; int f[N][N], v[N], w[N], h[N], ne[N], e[N], idx; int n, m; //a是b的父節點 void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; } //因為u是根節點,所以u是必選的 void dfs(int u) { //列舉子樹 for (int i = h[u]; i != -1; i = ne[i]) { int son = e[i];//記錄子樹的根節點 dfs(e[i]);//因為dfs是自下而上的,所以需要從下到上計算 for (int j = m - v[u]; j >= 0; j--)//因為u是該樹的根節點,所以必選,預留出u的空間 for (int k = 0; k <= j; k++)//列舉該子樹分配到的體積 f[u][j] = max(f[u][j], f[u][j - k] + f[son][k]);//加上該子樹的值 } //把物品u加進去,因為是根節點 for (int i = m; i >= v[u]; i--) f[u][i] = f[u][i - v[u]] + w[u]; for (int i = 0; i < v[u]; i++) f[u][i] = 0;//如果無法容納物品u,那他的價值為0; } int main() { memset(h, -1, sizeof(h)); scanf("%d%d", &n, &m); int anser; for (int i = 1; i <= n; i++) { int p; scanf("%d%d%d", &v[i], &w[i], &p); if (p == -1) anser = i;//尋找出祖宗節點 else add(p, i); } dfs(anser); printf("%d", f[anser][m]); return 0; }