HDOJ 4276 The Ghost Blows Light(树形DP)
Suddenly, alert occurred! The tomb will topple down in T minutes, and I should reach exit room in T minutes. Human beings die in pursuit of wealth, and birds die in pursuit of food! Although it is life-threatening time, I also want to get treasure out as much as possible. Now I wonder the maximum number of treasures I can take out in T minutes.
The first line contains two integer N and T. (1 <= n <= 100, 0 <= T <= 500)
Each of the next N - 1 lines contains three integers a, b, and t indicating there is a road between a and b which costs t minutes. (1<=a<=n, 1<=b<=n, a!=b, 0 <= t <= 100)
The last line contains N integers, which Ai indicating the number of treasure in the ith room. (0 <= Ai <= 100)
1 2 2
2 3 2
2 5 3
3 4 3
1 2 3 4 5
思路
1. 经典树形 DP 题目
2. 动规数组定义: dp[i][j] 表示从节点 i 出发使用最大花费为 j 后重新回到节点 i 能够得到的最大价值
3. 状态转移方程: dp[i][j] = dp[c1][k1] + dp[c2][k2] + ... + dp[cn][kn], c1, c2 ... cn 为节点 i 的孩子, k1, k2 ... kn 是在其对应的孩子节点分配的时间,
k1+k2+...kn <= j
4. 盗贼必须要跑出去, 因此最短路径上的时间需要预支. 以最短路径上的点(u)为树根求出以 u 为根的树分配 j 时间能够得到的最大收益 dp[u][j]
5. 然后再计算, 如何在最短路径上的节点分配时间使总收益最大, 这也是一步 DP, 具体来说, 这依然是一步树形 DP
6. 实现分为 3 部分, 第一部分使用 BFS(bellmanford, dijkstra) 算出最短路径的耗费以及最短路径上的所有点; 第二部分是 (4); 第三部分是 (5)
代码 from kedebug
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define max(a,b) (((a) > (b)) ? (a) : (b))
const int INF = 1e9; struct Node {
int y, w;
Node(int _y, int _w) : y(_y), w(_w) { }
}; vector<Node> map[];
int dp[][]; // dp[i][j] 从i出发又返回i,最大花费为j时所取得的价值
int val[], mark[]; int bfs(int s, int e)
{
int dist[], f[];
for (int i = ; i < ; ++i)
dist[i] = INF;
f[s] = -;
dist[s] = ;
queue<int> q;
q.push(s);
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = ; i < map[u].size(); ++i)
{
Node &v = map[u][i];
if (dist[v.y] > dist[u] + v.w)
{
f[v.y] = u;
dist[v.y] = dist[u] + v.w;
q.push(v.y);
}
}
}
for (int i = e; i != -; i = f[i])
mark[i] = ;
return dist[e];
} void dfs(int u, int pre, int mval)
{
dp[u][] = val[u];
for (int i = ; i < map[u].size(); ++i)
{
int y = map[u][i].y;
int w = map[u][i].w;
if (y == pre || mark[y])
continue;
dfs(y, u, mval); for (int j = mval; j >= ; --j)
for (int k = ; k <= j-*w; ++k)
if (dp[u][j-k-*w] != - && dp[y][k] != -)
dp[u][j] = max(dp[u][j], dp[y][k] + dp[u][j-k-*w]);
}
} int main()
{
int n, t;
while (scanf("%d %d", &n, &t) == )
{
memset(map, , sizeof(map));
memset(dp, -, sizeof(dp));
memset(mark, , sizeof(mark)); int a, b, c;
for (int i = ; i < n; ++i)
{
scanf("%d %d %d", &a, &b, &c);
map[a].push_back(Node(b, c));
map[b].push_back(Node(a, c));
}
for (int i = ; i <= n; ++i)
scanf("%d", &val[i]); int tt = bfs(, n);
if (tt > t)
{
printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");
continue;
}
for (int i = ; i <= n; ++i)
if (mark[i])
dfs(i, -, t - tt); int dp2[], tmax = t - tt;
memset(dp2, -, sizeof(dp2));
dp2[] = ;
for (int i = ; i <= n; ++i)
{
if (!mark[i])
continue;
for (int j = tmax; j >= ; --j)
{
for (int k = ; k <= j; ++k)
if (dp2[j-k] != - && dp[i][k] != -)
dp2[j] = max(dp2[j], dp2[j-k] + dp[i][k]); }
}
int ans = ;
for (int i = ; i <= tmax; ++i)
if (ans < dp2[i])
ans = dp2[i];
printf("%d\n", ans);
}
return ;
}
HDOJ 4276 The Ghost Blows Light(树形DP)的更多相关文章
- HDOJ 4276 The Ghost Blows Light
题意 1. 给定一棵树, 树上节点有 value, 节点之间 travel 有 cost. 给定起始节点和最大 cost, 求解最大 value 思路 1. 寻找最短路径 a. 题目描述中有两句话, ...
- HDU4276 - The Ghost Blows Light(树形DP)
题目大意 给定一棵n个结点的树,每个结点上有一定数量的treasure,经过每条边需要花一定的时间,要求你从结点1出发,在不超过时间T的情况下,最多能够获得的treasure是多少,并且要求结束于结点 ...
- HDU 4276 The Ghost Blows Light
K - The Ghost Blows Light Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & ...
- HDU 4276 The Ghost Blows Light(树形)
题意:给出一棵n个节点的树,起点1,终点n,相连的两个节点之间有距离,每个节点有个价值,给出一个时间T.问从1到达n在给定时间T内取得的最大价值? 思路:先从1走到n,如果总的时间不够走完,直接退出, ...
- HDU 4276 The Ghost Blows Light (树形DP,变形)
题意:给定一棵n个节点的树,起点是1,终点是n,每经过一条边需要消耗Ti天,每个点上有一定量的珠宝,要求必须在t天内到达终点才可以将珠宝带出去,问至多能带多少珠宝? 思路: 注意Ti可以为0,而且有可 ...
- 【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 ...
- BNUOJ 26283 The Ghost Blows Light
The Ghost Blows Light Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. O ...
- 【HDU4276】The Ghost Blows Light
题目大意:给定一棵有根树,1 号节点为根节点,点有点权,边有边权,初始给定一个价值,每经过一条边都会减少该价值,每经过一个点都会增加相应的答案贡献值,求如何在给定价值的情况下最大化答案贡献,并要求最后 ...
- HDU-4276 The Ghost Blows Light (树形DP+背包)
题目大意:在一个n个节点的树形迷宫中,1为起点,n为出口.每个节点上有一定价值的珠宝,在节点之间移动的时间已知,问在能走出迷宫的前提下并且不超过m的时间内能收集的最多珠宝是多少? 题目分析:在树上,从 ...
随机推荐
- gclient多源码管理工具 DEPS文件
gclient来管理源码的checkout, update等. gclient是google专门为这种多源项目编写的脚本,它可以将多个源码管理系统中的代码放在一起管理.甚至包括将Git和svn代码放在 ...
- PHP高级程序员必学
业务增长,给你的网站带来用户和流量,那随之机器负载就上去了,要不要做监控?要不要做负载均衡?用户复杂了,要不要做多终端兼容?要不要做CDN?数据量大了,要不要做分布?垂直分还是横向分?系统瓶颈在哪里? ...
- Java设计模式(9)适配器模式(Adapter模式)
适配器模式定义:将两个不兼容的类纠合在一起使用,属于结构型模式,需要有Adaptee(被适配者)和Adaptor(适配器)两个身份. 为何使用适配器模式 我们经常碰到要将两个没有关系的类组合在一起使用 ...
- SAP ML 物料分类账详解(含取消激活物料帐方法)
一.业务背景: 中国会计准则规定,对存货的核算必须采用历史成本法(即实际成本法).如果企业采用计划成本法或者定额成本法进行日常核算的,应当按期结转其成本差异,将计划成本或者定额成本调整为实际成本. “ ...
- 【WPF】鼠标拖拽功能DragOver和Drop
在Winform里面实现拖入功能只要设置控件AllowDrop=true; 然后实现方法 //拖入 private void txtInputPath_DragOver(object sender, ...
- elasticsearch系列二:索引详解(快速入门、索引管理、映射详解、索引别名)
一.快速入门 1. 查看集群的健康状况 http://localhost:9200/_cat http://localhost:9200/_cat/health?v 说明:v是用来要求在结果中返回表头 ...
- Java如何以(MMM)格式显示一个月份的名称?
JAVA中,如何以(MMM)格式显示一个月份的名称? 此示例显示如何使用Calender类的Calender.getInstance()方法和Formatter类的fmt.format()方法来显示( ...
- Java数组排序和搜索
如何排序数组并搜索其中的元素? 以下示例显示如何使用sort()和binarySearch()方法来完成任务.用户定义的方法printArray()用于显示数组输出: package com.yiib ...
- (转)小议TCP的MSS(最大分段)以及MTU
[前言]漫漫51长假,没有好的去处,只能每日上网消遣,某日逛到NBO灌水,见一帖曰:无法通过2514路由器上MSN(出口为ADSL线路,通过PPPoE)吾心想,ADSL---PPPoE,那肯定就是MT ...
- 开源轻量级分布式文件系统--FastDFS
FastDFS一个高效的分布式文件系统 分布式文件系统FastDFS原理介绍 分布式文件系统FastDFS设计原理 FastDFS安装.配置.部署(一)-安装和部署 分布式文件系统 - FastDFS ...