选课
作者:互联网
P2014 [CTSC1997] 选课 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
- 树上dp
- 由于这是一个森林,所以假设有0号结点连接所有的根,就变成了一颗树
- dp[now][j]代表以now为根节点,选择j门课程的最大答案
- 每次dp过程之前需要把子问题都求出来,也就是把当前now节点的子树的dp值求出(就是以子树的根为根节点,选择若干个点的答案),求出后就可以转换成01背包问题,dp中的k代表当前子树选择k个的更新过程
#include <bits/stdc++.h>
// https://www.luogu.com.cn/problem/P2014
using namespace std;
#define N 1e5
#define INF 2e9
#define MAX 1000
// 7 4
// 2 2
// 0 1
// 0 4
// 2 1
// 7 1
// 7 6
// 2 2
int head[MAX], idx;
struct Node
{
int to, nex;
} edge[MAX];
void add(int u, int v)
{
edge[++idx] = Node{v, head[u]};
head[u] = idx;
}
int dp[MAX][MAX];
int n, m;
void input()
{
cin >> n >> m;
for (int i = 1, fa; i <= n; i++)
{
scanf("%d%d", &fa, &dp[i][1]);
add(fa, i);
// add(0, i);
}
m++;
}
void dpp(int now)
{
for (int i = head[now]; i; i = edge[i].nex)
{
int to = edge[i].to;
dpp(to);
for (int j = m; j > 0; j--)
for (int k = 0; k < j; k++)
dp[now][j] = max(dp[now][j], dp[now][j - k] + dp[to][k]);
}
}
int main()
{
input();
dpp(0);
printf("%d",dp[0][m]);
}
标签:head,选课,int,MAX,now,dp,define 来源: https://www.cnblogs.com/Wang-Xianyi/p/16630173.html