题意:

  给一棵n个节点的树,点1为敌方基地,叶子结点都为我方阵地。我们可以在每个结点安放炸弹,每点至多放一个,每个结点有ki种炸弹可选,且每种炸弹有一个花费和一个攻击力(1点攻击力使敌人掉1点hp)。敌人的目的是我方阵地,任意路线都有可能,但规定只能往下跑。问当有m钱时,最坏情况下最多能打掉敌人多少hp?(n<1001, m<201, ki>=0)

思路:

  我竟然自己写出来了,咔咔~证明此题不难!

  注意:某些点可能没有炸弹可选(即不能放炸弹);有0花费的炸弹;最坏情况下指的是敌人总是跑攻击力最小的那条路径。

  本题说不出具体什么模型,混着来的。观察一下知道,如果本节点不放炸弹,那么所有子树就都得放炸弹,否则本节点往下走的攻击力必定为0。那么尽量炸弹放在更靠近根的地方应该是比较划算的(按常理)。

  同样,分析一个节点。本节点为根的子树的攻击力=min(每个子树的攻击力)+(本节点的攻击力),这是短板原理。然后再考虑本节点,如果买了,直接在短板上加攻击力,前提是本节点只允许放1炸弹。

  如何转移?先从将这子树花费为0的装进背包,如果有更好的再代替掉他。这一步暂时将dp[t][j]表示为以t为根的子树如果得到j元,至少能攻击敌人的hp。状态方程:dp[t][j]=max(dp[t][j],  min(dp[t][j-k], dp[e.to][k]));。为什么有个min?因为要取短板。注意初始化问题。

  由于可能会有免费炸弹,而每个点只需要考虑1个免费炸弹(只能放1个),其他免费炸弹删除掉(因为不划算啊),而且免费炸弹总是要先被考虑,否则的话就会重复。

  

 #include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <map>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=;
struct tower
{
int pri,pow;
}tow[N][]; struct node
{
int from,to,next;
node(){};
node(int from,int to,int next):from(from),to(to),next(next){};
}edge[N*]; int edge_cnt, head[N], cnt[N], dp[N][], n, m ;
void add_node(int from,int to)
{
edge[edge_cnt]=node(from, to, head[from]);
head[from]=edge_cnt++;
}
inline int cmp(tower a,tower b){return a.pri<b.pri;} void DFS(int t,int far)
{
node e;
int flag=;
for(int i=head[t]; i!=-; i=e.next)
{
e=edge[i];
if(e.to==far) continue;
DFS(e.to, t); for(int j=m; j>=; j-- ) //容量
{
dp[t][j]=min(dp[t][j], dp[e.to][]); //先装代价为0的,如果有更好的再代替掉。
for(int k=; k<=j; k++ ) //给此孩子k元,得到的最大攻击力。
dp[t][j]=max(dp[t][j], min(dp[t][j-k], dp[e.to][k]));
}
flag=; //标记是否叶子。
}
if(flag==) memset(dp[t], , sizeof(dp[t])); //叶子节点 //本节点的决策是01背包模型: 买 or 不买。(不买就只能靠孩子来防御)
for(int j=m; j>=; j-- ) //容量
{
int k=;
for( ; k<cnt[t] && !tow[t][k].pri; k++ ) //不用钱的,只留1个power最大的.
if(tow[t][k-].pow > tow[t][k].pow)
swap(tow[t][k],tow[t][k-]); for( k-- ; k<cnt[t]; k++) //物品
{
if(j-tow[t][k].pri>=)
dp[t][j]=max(dp[t][j], dp[t][j-tow[t][k].pri] + tow[t][k].pow ); //可以直接挡
}
}
} int main()
{
freopen("input.txt", "r", stdin);
int t, a, b; cin>>t;
while(t--)
{
edge_cnt=;
memset(head, -, sizeof(head));
memset(dp, 0x3f, sizeof(dp)); //注意初始化 scanf("%d",&n);
for(int i=; i<n; i++) //无向图
{
scanf("%d%d",&a,&b);
add_node(a,b);
add_node(b,a);
} scanf("%d",&m); //钱。
for(int i=; i<=n; i++)
{
scanf("%d",&cnt[i]);
for(int j=; j<cnt[i]; j++)
scanf("%d%d", &tow[i][j].pri, &tow[i][j].pow);
sort(tow[i], tow[i]+cnt[i], cmp); //免费的排前面
}
DFS(, -);
printf("%d\n",dp[][m]);
}
return ;
}

AC代码

HDU 4044 GeoDefense (树形DP,混合经典)的更多相关文章

  1. HDU 2196 Computer 树形DP经典题

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...

  2. HDU 2196 Computer 树形DP 经典题

    给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...

  3. HDU 4044 GeoDefense(动态规划)

    GeoDefense Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  4. HDU 2196.Computer 树形dp 树的直径

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  5. 洛谷 P1352 没有上司的舞会【树形DP】(经典)

    <题目链接> <转载于>>> > 题目描述: 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的 ...

  6. hdu 6201 【树形dp||SPFA最长路】

    http://acm.hdu.edu.cn/showproblem.php?pid=6201 n个城市都在卖一种书,该书的价格在i城市为cost[i],商人打算从某个城市出发到另一个城市结束,途中可以 ...

  7. hdu 4081 最小生成树+树形dp

    思路:直接先求一下最小生成树,然后用树形dp来求最优值.也就是两遍dfs. #include<iostream> #include<algorithm> #include< ...

  8. HDU 3899 简单树形DP

    题意:一棵树,给出每个点的权值和每条边的长度, 点j到点i的代价为点j的权值乘以连接i和j的边的长度.求点x使得所有点到点x的代价最小,输出 虽然还是不太懂树形DP是什么意思,先把代码贴出来把. 这道 ...

  9. HDU 4044 GeoDefense

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

  10. HDU 4714 Tree2cycle (树形DP)

    题意:给定一棵树,断开一条边或者接上一条边都要花费 1,问你花费最少把这棵树就成一个环. 析:树形DP,想一想,要想把一棵树变成一个环,那么就要把一些枝枝叶叶都换掉,对于一个分叉是大于等于2的我们一定 ...

随机推荐

  1. AngularJS系统学习之$watch(监控)

    在scope的内置的所有函数中,用的最多的可能就是$watch函数了, 当你的数据模型中某一部分发生变化时,$watch函数可以向你发出通知. 你可以监控单个对象的属性,亦可以监控需要经过计算的结果( ...

  2. [poj2186]Popular Cows(targin缩点)

    题意:求其他所有牛都认为其牛的牛的个数. 解题关键:targin算法模板题,缩点形成一棵树,并不一定是棵树,可能含有多个入度为0的点,寻找出度为0的点(缩点之后的点)的个数,如果个数大于0,则无解,否 ...

  3. tetrahedron

    题意: 求解一个四面体的内切球. 解法: 首先假设内切球球心为$(x0,x1,x2)$,可以用$r = \frac{3V}{S_1+S_2+S_3+S_4}$得出半径, 这样对于四个平面列出三个方程, ...

  4. JSP页面无法识别EL表达式

    昨天一直纠结一个问题,JSP页面无法获取${user}的值,一直显示的是${user},今天解决了,原来是JSP页面无法识别EL表达式. 我的web.xml的声明如下: <!DOCTYPE we ...

  5. Maven面试必备

    Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Depen ...

  6. win7 mongod不是内部命令

    1.下载MongoDB 1.1 MongoDB下载 1.2 选择Server下面的 Community 2.安装MongoDB 2.1 注意事项:一直下一步就行了,但是遇到下面这个界面,注意一定要去掉 ...

  7. Easyui TextBox 添加事件的方法

    $("#txtPaySideId").textbox('textbox').bind("click", function () { showPlatform() ...

  8. 51nod 1449 砝码称重【天平/进制】

    题意: 给你w,n,问你在w^0,w^1,w^2...各种一个,问你能不能用这些砝码和重量为m的东西放在天平上使得天平平衡: 思路: 这个很容易联想到进制: 如果把m放在是一边的话,其实对于砝码就是纯 ...

  9. Codeforces 1119D(贡献计算)

    题目传送 排序看一看. 关键点在于发现性质: 算一个点的贡献时: 1.与后一个有重叠.\[当 a[i] + r >= a[i + 1] + l, 即 r - l >= a[i + 1] - ...

  10. 洛谷 P4174 [NOI2006]最大获利 && 洛谷 P2762 太空飞行计划问题 (最大权闭合子图 && 最小割输出任意一组方案)

    https://www.luogu.org/problemnew/show/P4174 最大权闭合子图的模板 每个通讯站建一个点,点权为-Pi:每个用户建一个点,点权为Ci,分别向Ai和Bi对应的点连 ...