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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人