hdu4044 依赖背包变形 好题!
由于不是求最大的可拦截的HP值,而是要将最小值最大化,那么就需要分配每个子树用的钱数以达到最小值最大化
第一步解决如何分配钱使得结点u的子树中用了j元钱后可以拦截的HP最大,这就是变形的分组(依赖)背包,即枚举m元钱,在子树v用t元钱,在v之前的子树用j-t元钱
用Max[v][j]数组记录u的前v个结点花j元钱可以拦截的最大HP,Max[v][j]=max{min( dp[v][t] , Max[v-i][j-t] )},第一维v可以压缩掉
第二步考虑结点u上建立什么炮塔,用Max数组来求出dp[u][j]即可
/*
给定一棵树,m块钱,每个结点上可以建造k种(价格price,攻击力power)防御塔
求可以阻拦的最大血量
dp[i][j]表示子树i中花费j元可以抵挡的怪物血量 */
#include<bits/stdc++.h>
using namespace std;
#define maxn 1050
struct Edge{int to,nxt;}edge[maxn<<];
struct node{int k,price[],power[];}p[maxn];
int n,m,head[maxn],tot,dp[maxn][],flag[maxn];
void init(){
tot=;
memset(head,-,sizeof head);
memset(flag,,sizeof flag);
}
void addedge(int u,int v){
edge[tot].to=v;edge[tot].nxt=head[u];head[u]=tot++;
}
void dfs(int u,int pre){
//init,每个点只能建立一个塔嘛
for(int j=m;j>=;j--)
for(int i=;i<=p[u].k;i++)
if(j>=p[u].price[i])
dp[u][j]=max(dp[u][j],p[u].power[i]); if(flag[u]==&&u!=)return;//叶子节点退出 for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(v!=pre)dfs(v,u);
} //Max[i][j]表示给前i个儿子花费j元时可以拦截的最大hp,可压成滚动数组
int Max[];
memset(Max,0x3f,sizeof Max);
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(v==pre)continue;
for(int j=m;j>=;j--){//给子树v之前的子树用j元
int maxx=;
for(int t=;t<=j;t++)//给子树v用t元
maxx=max(maxx,min(dp[v][t],Max[j-t]));//找出最优的分配方式
Max[j]=maxx;//记录
}
} //最后Max数组表示给u的子树总共花i元可以拦截的最大HP
for(int j=m;j>=;j--)
for(int t=;t<=j;t++)//给子树花费t,给自己花费j-t元
dp[u][j]=max(dp[u][j],dp[u][j-t]+Max[t]);
//printf("%d\n",u);
//for(int i=1;i<=m;i++)
// printf("%d ",dp[1][i]);
}
int main(){
int t,u,v;
cin>>t;
while(t--){
init();
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
flag[u]++;flag[v]++;
}
scanf("%d",&m);
for(int i=;i<=n;i++){
scanf("%d",&p[i].k);
for(int j=;j<=p[i].k;j++)
scanf("%d%d",&p[i].price[j],&p[i].power[j]);
}
memset(dp,,sizeof dp);
dfs(,);
printf("%d\n",dp[][m]);
}
}
hdu4044 依赖背包变形 好题!的更多相关文章
- 依赖背包变形——poj1947(经典)
/*这题显然不适用依赖背包的优化,因为不能保证根是必选的,但是可以按照常规依赖背包的思路进行转移,即每次对一个儿子进行C^2的转移 还是树形的背包,dp[u][j]表示u的子树里,切割出一个大小为j的 ...
- 依赖背包变形(经典)——poj1155
这个题用优化后的依赖背包做难以实现,所以用常规的泛化物品的和来做即可 每个节点的容量定义为这个节点下的叶子结点个数,dp[u][j]用来表示节点u下选取j个物品的最大收益,最后从m-0查询dp[1][ ...
- 依赖背包——cf855C好题
比较裸的依赖背包,但是想状态还是想了好久 转移时由于边界问题,虽然可以倒序转移,但当容量为0|1的时候,由于有初始值的存在 很难再原dp数组上进行修改,所以额外用tmp数组来保存修改后的值 #incl ...
- HDU-4044 树形背包dp好题
不会做,题解是参考网上的.感觉这道题是到好题,使得我对树形背包dp更了解了. 有几个注意的点,直接给出代码,题解以及注意点都在注释里了. #include<bits/stdc++.h> u ...
- 依赖背包变形——hdu4003
思维性比较强,代码挺简单的,dp[u][j]表示在u子树下安排j个机器人,让其不回u 注意转移时的初始值 /* dp[u][j]为在子树u有j个机器人不回来 */ #include<bits/s ...
- hdu 1561 The more, The Better (依赖背包 树形dp)
题目: 链接:点击打开链接 题意: 非常明显的依赖背包. 思路: dp[i][j]表示以i为根结点时攻击j个城堡得到的最大值.(以i为根的子树选择j个点所能达到的最优值) dp[root][j] = ...
- cf581F 依赖背包+临时数组 好题
这题得加个临时数组才能做.. /* 给定一棵树,树节点可以染黑白,要求叶子节点黑白平分 称连接黑白点的边为杂边,求使得杂边最少的染色方 那么设dp[i][j][0|1]表示i子树中有j个叶子节点,i染 ...
- 【HDU 4276】The Ghost Blows Light(树形DP,依赖背包)
The Ghost Blows Light Problem Description My name is Hu Bayi, robing an ancient tomb in Tibet. The t ...
- Codeforces Round #214 (Div. 2) C. Dima and Salad (背包变形)
C. Dima and Salad time limit per test 1 second memory limit per test 256 megabytes input standard in ...
随机推荐
- MGR架构~ 整体性能架构的调优
一 简介:MGR集群架构的调优二 过程:本文将从各个角度来具体阐述下三 硬件 1 硬件选择相同配置的服务器,磁盘,内存,cpu性能越高越好四 网络 1 0丢包和最好万兆网卡五 MGR本身 ...
- (7)Java数据结构--集合map,set,list详解
MAP,SET,LIST,等JAVA中集合解析(了解) - clam_clam的专栏 - CSDN博---有颜色, http://blog.csdn.net/clam_clam/article/det ...
- 解决微信小程序使用switchTab跳转后页面不刷新的问题
wx.switchTab({ url: '../index/index', success: function(e) { var page = getCurrentPages().pop(); if ...
- 【ARTS】01_16_左耳听风-20190225~20190303
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- mysql select in 怎么优化
2017年7月10日 22:36:54 星期一 原理: 把select where in 变换成 "where = " 或者 "where between and &qu ...
- FreeSWITCH异常原因总结
最经在玩FreeSWITCH的时候,遇到很多的问题,特此总结一下,希望以后不要犯类似的错误了: 1.Client端无法注册,但是FS运行正常? 解决办法:查看防火墙是否关闭./etc/init.d/i ...
- 最新sublime text 3 注册码license分享(亲测有效)
—– BEGIN LICENSE —– TwitterInc 200 User License EA7E-890007 1D77F72E 390CDD93 4DCBA022 FAF60790 61AA ...
- MinGW-w64非官方编译器集成安装包(很清楚)
官方链接[编辑] MinGW 官方网站. SourceForge.net上的MinGW官方的下载站点(Win32系统). MinGW-w64官方的下载站点[编辑] MinGW-w64是2005年由On ...
- awk简单用法-(1)
一.awk基本操作 awk指定多个分割符,分隔符中有:和空格,还有:和空格的组合,这个时候需要指定多个分隔符 -F'[ :]+',[ :]表示分隔符为:和空格,一个或者多个+号表示空格和:的组合也为一 ...
- .NET NPOI操作Excel 让单元格的内容换行
HSSFWorkbook workbook = new HSSFWorkbook(); // 工作簿 ISheet sheet = workbook.CreateSheet("会员列表&qu ...