本文主要是介绍AW286 选课(背包类树形DP),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目地址
易错点:
- 分组背包需要反向循环以保证状态转移的正确性.
- f[x][0]在dp前就初始化了,因此可以不枚举体积为0的情况.
- 注意初始化.
#include<cstdio>
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
const int MAXN=500;
int f[MAXN][MAXN],score[MAXN];
vector<int> son[MAXN];
int m;
void dp(int x){f[x][0]=0;if(!son[x].empty()){int size=son[x].size();for(int i=0;i<size;i++){int y=son[x].at(i);dp(y);for(int j=m;j>=1;j--){for(int k=1;k<=j;k++){f[x][j]=max(f[x][j],f[x][j-k]+f[y][k]);}}}}if(x!=0){for(int i=m;i>=1;i--){f[x][i]=f[x][i-1]+score[x];}}
}
int main(){memset(f,0xcf,sizeof(f));int n;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){int fa,nowScore;scanf("%d%d",&fa,&nowScore);son[fa].push_back(i);score[i]=nowScore;}dp(0);printf("%d\n",f[0][m]);return 0;
}
这篇关于AW286 选课(背包类树形DP)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!