正解思路
设 表示以 为根的子树中选 门课程能够获得的最高学分,设 的子节点集合为 ,子节点个数 修完 这门课后,对于 的每个子节点 ,我们可以在以 为根的子树中选修若干门课(记为 ) ,在满足 的基础上获得尽量多的学分。
不难看出,动态转移方程为
其中
其中
正解代码
#include<bits/stdc++.h>
using namespace std;
const int N=1512;
vector<int> son[N];
int f[N][N],s[N],n,m;
void dp(int x){
int y;
f[x][0]=0;
for(int i=0;i<son[x].size();i++){
y=son[x][i];
dp(y);
for(int t=m;t>-1;t--){
for(int j=t;j>-1;j--){
f[x][t]=max(f[x][t],f[x][t-j]+f[y][j]);
}
}
}
if(x!=0){
for(int t=m;t>0;t--){
f[x][t]=f[x][t-1]+s[x];
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
int x;
cin>>x>>s[i];
son[x].push_back(i);
}
memset(f,0xc0,sizeof(f));
dp(0);
cout<<f[0][m];
return 0;
}