题目
题解
一道树形
DP
\text{DP}
DP题,令
u
\text{u}
u为
v
\text{v}
v父亲节点,那么转态转移方程为:
f
[
u
]
[
j
]
=
max
(
f
[
u
]
[
j
−
k
]
+
f
[
v
]
[
k
]
,
f
[
u
]
[
j
]
)
f[u][j] = \max(f[u][j - k] + f[v][k], f[u][j])
f[u][j]=max(f[u][j−k]+f[v][k],f[u][j])
code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 105;
template <typename T>
inline void read(T &s) {
s = 0;
T w = 1, ch = getchar();
while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }
while (isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
s *= w;
}
int n, m, rt, tot;
int lin[maxn], v[maxn], w[maxn], f[maxn][maxn];
struct node { int next, to; } edge[maxn];
inline int min(int aa, int bb) { return aa < bb ? aa : bb; }
inline int max(int aa, int bb) { return aa > bb ? aa : bb; }
inline void add(int from, int to) {
edge[++tot].to = to;
edge[tot].next = lin[from];
lin[from] = tot;
}
void dfs(int x) {
for (int i = lin[x]; i; i = edge[i].next) {
int y = edge[i].to;
// cout << "y : " << y << endl;
dfs(y);
for (int j = m - v[x]; j >= 0; --j) {
for (int k = 0; k <= j; ++k) {
f[x][j] = max(f[x][j], f[x][j - k] + f[y][k]);
}
}
}
for (int i = m; i >= v[x]; --i) {
f[x][i] = f[x][ i - v[x] ] + w[x];
}
for (int i = 0; i < v[x]; ++i) {
f[x][i] = 0;
}
}
int main() {
read(n), read(m);
int x;
for (int i = 1; i <= n; ++i) {
read(v[i]), read(w[i]), read(x);
if (x == -1) rt = i;
else add(x, i);
}
dfs(rt);
// cout << "rt : " << rt << endl;
printf("%d\n", f[rt][m]);
return 0;
}