题解AcWing10有依赖的背包问题
Posted xsl19
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解AcWing10有依赖的背包问题相关的知识,希望对你有一定的参考价值。
树形 DP 的经典问题。
我们设 (dp_{i,j}) 表示当前节点为 (i),当前节点的子树(包含当前节点)最多装的体积是 (j) 的最大价值。
我们遍历节点的过程就相当于做了一遍分组背包。
注意遍历完所有子节点后要更新一下状态。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 103;
int n, m;
int tot, head[maxn], ver[maxn * 2], nxt[maxn * 2];
int dp[maxn][maxn];
int v[maxn], w[maxn], p[maxn];
inline void add(int u, int v)
{
ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;
}
void dfs(int u, int f)
{
for (int i = head[u]; i; i = nxt[i]) //循环组数
{
int vv = ver[i];
if (vv == f) continue;
dfs(vv, u); //遍历子节点
for (int j = m - v[u]; j >= 0; j-=1) //循环体积
for (int k = 0; k <= j; k+=1) //循环决策
dp[u][j] = max(dp[u][j], dp[u][j - k] + dp[vv][k]); //状态转移
}
//更新状态
for (int i = m; i >= v[u]; i-=1) dp[u][i] = dp[u][i - v[u]] + w[u];
for (int i = 0; i < v[u]; i+=1) dp[u][i] = 0;
}
int main()
{
cin >> n >> m;
int rt = -1; //根节点
for (int i = 1; i <= n; i+=1)
{
cin >> v[i] >> w[i] >> p[i];
if (p[i] == -1) rt = i;
else add(i, p[i]), add(p[i], i); //建树
}
dfs(rt, 0);
cout << dp[rt][m] << endl;
return 0;
}
以上是关于题解AcWing10有依赖的背包问题的主要内容,如果未能解决你的问题,请参考以下文章