1576 选课
有些课程需要一定的基础知识,必须在选了其他的一些课程基础上才能选修,可以看出是一个树形结构
请找出一种选课方案使得你能得到的学分最多,可以看出是一个动态规划
所以综合一下,这是一个树形DP (我就是按着树形DP练的)
其实这道题更像一个有依赖性的背包
设f[i][j]表示以i作为节点,选取j个节点的最优值
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
const int SIZE=5000;
const int inf=9999999;
int n,m;
vector<int> e[SIZE];
int a[SIZE];
int f[SIZE][SIZE];
void dfs(int x)
{
f[x][0]=0;//边界值
for(int i=0;i<e[x].size();i++)
{
int y=e[x][i];//获取子节点;
dfs(y);
for(int t=m;t>=0;t--)//枚举m个点
{
for(int j=t;j>=0;j--)//枚举t个点
{
f[x][t]=max(f[x][t],f[x][t-j]+f[y][j]);
}
}
}
if(x)
{
for(int t=m;t>=0;t--)
{
f[x][t]=f[x][t-1]+a[x];
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int x;
cin>>x>>a[i];
e[x].push_back(i);//表示x是i的父亲
}
memset(f,207,sizeof(f));
dfs(0);
cout<<f[0][m]<<endl;//选择m个的最大价值
return 0;
}