[CTSC1997] 选课
作者:互联网
[CTSC1997] 选课
人生中的第一道树形 \(DP\) .
这是一道树形 \(DP\) , 很显然, 这个题的课程关系是一个森林, 我们把 \(0\) 节点也算上, 就成了一棵树.
我们设状态 \(f[u][i]\) 表示以 \(u\) 为根节点的子树中选 \(i\) 个课程的最大学分.
转移: \(f[u][i] = max(f[v1][j1] + f[v2][j2] + ...)\) , \(\sum j = i\) .
\(code:\)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int read() {
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') f = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
const int N = 305;
int n, m, f[N][N];
int tot, to[N], nxt[N], head[N];
void add(int u, int v) {
to[++tot] = v, nxt[tot] = head[u], head[u] = tot;
}
void dfs(int x) {
for (int i = head[x]; i; i = nxt[i]) {
int y = to[i];
dfs(y);
for (int j = m; j >= 1; j--) {
for (int k = 0; k < j; k++) {
f[x][j] = max(f[x][j], f[y][k] + f[x][j - k]);
}
}
}
}
int main() {
n = read(), m = read() + 1;
for (int i = 1; i <= n; i++) {
int k = read(); f[i][1] = read();
add(k, i);
}
dfs(0);
printf("%d", f[0][m]);
return 0;
}
标签:ch,CTSC1997,选课,int,read,isdigit 来源: https://www.cnblogs.com/sshadows/p/P2014.html