树形DP,和背包差不多。dp[now][x]表示now这个节点的子树上,花费为x的时候,获得的最大防御能力(保证敌方HP<=0)

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std; const int maxn = + ;
int T, n, m;
vector<int>tree[maxn];
struct kind
{
int price;
int power;
kind(int a, int b){ price = a; power = b; }
};
vector<kind>v[maxn];
bool vis[maxn];
int dp[maxn][ + ];
int flag[ + ], tmp[ + ]; void init()
{
for (int i = ; i <= n; i++) tree[i].clear();
for (int i = ; i <= n; i++) v[i].clear();
memset(vis, , sizeof vis);
memset(dp, -, sizeof dp);
} void read()
{
scanf("%d", &n);
for (int i = ; i <= n - ; i++)
{
int u, v;
scanf("%d%d", &u, &v);
tree[u].push_back(v);
tree[v].push_back(u);
}
scanf("%d", &m); for (int i = ; i <= n; i++)
{
int ki;
scanf("%d", &ki);
while (ki--)
{
int pricei, poweri;
scanf("%d%d", &pricei, &poweri);
kind k(pricei, poweri);
v[i].push_back(k);
}
}
} void dfs(int now)
{
bool fail = ;
for (int i = ; i<tree[now].size(); i++)
if (!vis[tree[now][i]]) fail = ; if (fail)
{
for (int i = ; i<v[now].size(); i++)
dp[now][v[now][i].price] = max(dp[now][v[now][i].price], v[now][i].power);
return;
} bool d[maxn];
memset(d, , sizeof d);
for (int i = ; i<tree[now].size(); i++)
{
if (vis[tree[now][i]]) continue; int id = tree[now][i];
vis[id] = ; dfs(id); d[i] = ;
} memset(flag, -, sizeof flag); bool first = ; for (int i = ; i<tree[now].size(); i++)
{
if (!d[i]) continue; int id = tree[now][i]; if (first)
{
first = ;
for (int j = ; j <= m; j++) flag[j] = dp[id][j];
} else
{
memset(tmp, -, sizeof tmp);
for (int j = ; j <= m; j++)
for (int k = ; k <= m; k++)
if (dp[id][j] != - && flag[k] != - && j + k <= m)
tmp[j + k] = max(tmp[j + k], min(dp[id][j], flag[k]));
for (int j = ; j <= m; j++) flag[j] = tmp[j];
}
} for (int i = ; i<v[now].size(); i++)
for (int j = m; j >= v[now][i].price; j--)
if (flag[j - v[now][i].price] != -)
dp[now][j] = max(dp[now][j], flag[j - v[now][i].price] + v[now][i].power); for (int i = ; i <= m; i++) dp[now][i] = max(dp[now][i], flag[i]); for (int i = ; i<v[now].size(); i++)
dp[now][v[now][i].price] = max(dp[now][v[now][i].price], v[now][i].power);
} void work()
{
vis[] = ;
dfs();
int ans = ;
for (int i = ; i <= m; i++) ans = max(ans, dp[][i]);
printf("%d\n", ans);
} int main()
{
scanf("%d", &T);
while (T--)
{
init();
read();
work();
}
return ;
}

最新文章

  1. Atian inputmethod 输入法解决方案 方言与多语言多文字支持 英语汉字汉语阿拉伯文的支持 (au
  2. C++ 基础 构造函数的使用
  3. 慕课网-安卓工程师初养成-6-5 使用循环操作 Java 中的数组
  4. 利用Junit4进行程序模块的测试,回归测试
  5. 验证坐标在某片坐标区域内 php 代码
  6. extjs grid 单元格 多选
  7. C# MySql分页存储过程的应用
  8. select默认选择的实现方法
  9. cocoapod安装失败解决
  10. 一个标准的WebView示例
  11. 数据挖掘---Matplotib的学习
  12. jmeter 获取数据库表数据作为参数
  13. Nginx限制下载速度
  14. DOM 操作技术【JavaScript高级程序设计第三版】
  15. odoo开发基础--模型之基本字段类型
  16. node 问题
  17. Java工具-----native2ascii
  18. 【mongodb】Mongodb初识
  19. leetcode421
  20. 安装jdk1.8,编写环境变量

热门文章

  1. CSS单行、多行文本溢出显示省略号(……)
  2. RS485 介绍
  3. echarts学习总结(二):一个页面存在多个echarts图形,图形自适应窗口大小
  4. MFC笔记&lt;持续更新&gt;
  5. iOS 开发之照片框架详解
  6. 学习笔记——桥接模式Bridge
  7. asp读取指定目录下的文件名
  8. zencart 新页面调用好功能代码集:
  9. C++头文件#include&lt;bits/stdc++.h&gt;
  10. 【dp】 poj 1953