题意:

  给一棵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. MongoDB -- 安装(win 10)

    1. 下载安装包: mongodb-win32-x86_64-2008plus-ssl-4.0.10-signed.msi https://www.mongodb.com/download-cente ...

  2. C++ TUTORIAL - MEMORY ALLOCATION - 2016

    http://www.bogotobogo.com/cplusplus/memoryallocation.php Variables and Memory Variables represent st ...

  3. Httpclient入门代码

    /** * Project Name:httpClient * File Name:Test.java * Package Name:httpClient * Date:2017年11月9日上午8:3 ...

  4. ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 26. 缓存

    In-Memory 使用IMemeryCache接口 注册缓存 HomeController注入进来 建一个类,用来存缓存的常量 判断缓存里面是否有数据,如果没有就读数据库存起来. 设置缓存事件,可调 ...

  5. python 并发编程之IO 模型

    首先说一下 IO 发生时涉及的对象和步骤.以read 为例,会经历两个阶段: 1)等待数据准备 2)将数据从内核拷贝到进程中 二,阻塞Io(blocking IO) 在 Linux中  默认情况下所有 ...

  6. CCF 201604-2 俄罗斯方块 (模拟)

    问题描述 俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游戏. 游戏在一个15行10列的方格图上进行,方格图上的每一个格子可能已经放置了方块,或者没有放置方块.每一轮,都会有一个新的由4个小方 ...

  7. C#简单的国际化

    1.新建一个资源文件夹,并在资源文件夹新建中英问的资源文件,如图: 2.中英文资源文档添加资源,如图: 3.Program.cs中添加根据系统语言确定中英文,这里默认为英文: using Intern ...

  8. LeetCode: 575 Distribute Candies(easy)

    题目: Given an integer array with even length, where different numbers in this array represent differe ...

  9. numpy.ndarray常用属性和方法

    import numpy as np a = np.array([[1,2,3],[4,3,2],[6,3,5]])print(a) [[1 2 3] [4 3 2] [6 3 5]] print(a ...

  10. 三轴陀螺仪与加速度计如何辅助 iPhone 定位的

    在所有之前解释一下陀螺仪 根据Wiki的定义:「陀螺仪是用于测量角度或维持方向的设备,基于角动量守恒原理.」 这句话的要点是测量角度或维持方向,这是 iPhone 4 为何搭载此类设备的原因.机械陀螺 ...