- f[0][m]可知f[i][j]是以i为根节点的子树有的值,其中不包括i
- 背包问题倒着循环--
- 注意vector的使用 son[fa].push_back(i)即输入 son[x].size长度查询
遗留问题:
- ·背包为什么倒着循环
- ·本题中f[x][t]=max(f[x][t],f[x][t-j]+f[y][j]);是否会重复计算
- ·tj循环能不能放在大括号外
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
vector<int>son[500];
int f[500][500],s[310],n,m;
void dp(int x) {
f[x][0]=0;
for(int i=0;i<son[x].size();i++) {
int y=son[x][i];
dp(y);
for(int t=m;t>=0;t--)
for(int j=t;j>=0;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() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) {
int fa;
scanf("%d%d",&fa,&s[i]);
son[fa].push_back(i);
}
memset(f,0xcf,sizeof(f));
dp(0);
cout<<f[0][m]<<endl;
return 0;
}
子树背包DP详解
本文深入探讨了子树背包动态规划问题,详细解析了如何利用背包DP思想解决以树形结构为背景的问题。通过倒序循环优化算法,避免了重复计算,确保了计算效率和准确性。文章还特别讨论了向量在数据结构中的应用,以及如何通过子节点向量的大小进行查询,为读者提供了完整的代码实现。
238

被折叠的 条评论
为什么被折叠?



