从这篇博客往前到二叉苹果树都可以用分组背包做

这依赖性的问题,都可以用于这道题类似的方法来做

表示以i为根的树中取j个节点所能得的最大价值

那么每一个子树可以看成一个组,每个组里面取一个节点,两个节点,三个节点就是三个不同的物品

对于这道题,有

我们来类比一下普通分组背包的转移方程

这里的k表示第几组,而在树上就直接用i表示,因为i已经包含它的子树的信息了

然后 相当于, 后面的相当于

然后注意k不能等于0,因为k=0就不会减去w了,本身的值就是k=0的情况

#include<cstdio>
#include<vector>
#include<cstring>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std; const int MAXN = 3123;
int f[MAXN][MAXN], cnt[MAXN], n, m;
struct node { int v, w; };
vector<node> g[MAXN]; void dfs(int u, int fa)
{
REP(i, 0, g[u].size())
{
int v = g[u][i].v, w = g[u][i].w;
if(v == fa) continue;
dfs(v, u);
cnt[u] += cnt[v]; for(int j = cnt[u]; j >= 1; j--)
REP(k, 1, min(j, cnt[v]) + 1)
f[u][j] = max(f[u][j], f[u][j-k] + f[v][k] - w);
}
} int main()
{
scanf("%d%d", &n, &m);
REP(u, 1, n - m + 1)
{
int k, v, w;
scanf("%d", &k);
REP(i, 0, k)
{
scanf("%d%d", &v, &w);
g[u].push_back(node{v, w});
}
} memset(f, 0xc0, sizeof(f));
REP(i, 1, n + 1) f[i][0] = 0;
REP(i, n - m + 1, n + 1)
{
cnt[i] = 1;
scanf("%d", &f[i][1]);
} dfs(1, 0);
for(int i = m; i >= 0; i--)
if(f[1][i] >= 0)
{
printf("%d\n", i);
break;
} return 0;
}

最新文章

  1. (js) 输入框只能输入中文、英文、数字、@符号和.符号
  2. 安利一个MVC的好东西,RazorGenerator.MsBuild,可以自动编译cshtml文件
  3. strcat函数的使用需要注意的问题
  4. leetcode:Rectangle Area
  5. Android四大组件——Activity
  6. (c#)WinForm遍历所有控件
  7. MPQ Storm库 源代码分析 一个
  8. Ng-model undefined in the controller
  9. java多线程(7)---Condition
  10. Dynamics 365-部分用户访问环境缓慢
  11. discuz 3.1论坛快照被百度劫持解决方案
  12. 026 UI调试
  13. Ubuntu16.04配置Eclipse开发OpenCV
  14. thinkphp链接多个数据库时怎么调用M方法?
  15. LeetCode——150. Evaluate Reverse Polish Notation
  16. 用JS 和 jQery获取屏幕的高度和宽度
  17. oracle的sql语句大小写
  18. GIT使用(自用)
  19. 集合框架(01)Collection
  20. UITableView中的dequeueReusableCellWithIdentifier的方法

热门文章

  1. asp.net DataTables
  2. LCD段码驱动
  3. SQL中的union
  4. ZBrush功能特性之变形
  5. checkbox控制显示隐藏
  6. NOIp2018模拟赛三十五
  7. puppet介绍与安装
  8. 关于 Error: No PostCSS Config found in 的错误
  9. Linux学习总结(12)——Linux必须学会的60个命令
  10. POJ——T 3041 Asteroids