树形DP(01组合背包The Ghost Blows Light HDU4276)
题意:有n个房间,之间用n-1条道路连接,每个房间都有一个定时炸弹,在T时间后会一起爆炸,第i个房间有pi价值的珠宝,经过每条道路都需要花费一定的时间,一个人从1房间开始 ,从n房间出去,保证再不炸死的情况下可以带走的最大价值的珠宝是多少?
分析:很容易想到,这是树上的01背包,可以抽象的想,要是珠宝价值最大即满足:1到n的路径必须经过,且经过一次,而与该路径相连的副路径要么走0次要么走2次 (因为还有回来),所以用DP[i][j]表示以i为根节点的子树,花费j的时间可以获得的最大价值,需要特殊处理的是1-n经过的路径时间花费全部设为0,然后以1为根节点dfs,最后DP[1][T-ans]+value[1]就是最大值,下面是动态方程:
for(int j=cost;j>=edge[i].w*2;j--)
{
for(int k=0;k<=j-edge[i].w*2;k++)
dp[u][j]=max(dp[u][j],dp[u][j-edge[i].w*2-k]+value[v]+dp[v][k]);//u为子树是经过j时间获得的最大价值
}
程序:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"queue"
#include"algorithm"
#include"string.h"
#include"string"
#include"math.h"
#include"vector"
#include"stack"
#include"map"
#define eps 1e-4
#define inf 0x3f3f3f3f
#define M 209
#define PI acos(-1.0)
using namespace std;
struct node
{
int u,v,w,next;
}edge[M*2];
int t,head[M],fa[M],pre[M],dp[M][555],value[M];
void init()
{
t=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)
{
edge[t].u=u;
edge[t].v=v;
edge[t].w=w;
edge[t].next=head[u];
head[u]=t++;
}
void dfs(int u,int f)
{
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v==f)continue;
fa[v]=u;
pre[v]=i;
dfs(v,u);
}
}
void dfs1(int u,int f,int cost)
{
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v==f||cost-edge[i].w*2<0)continue;
dfs1(v,u,cost-edge[i].w*2);
for(int j=cost;j>=edge[i].w*2;j--)
{
for(int k=0;k<=j-edge[i].w*2;k++)
dp[u][j]=max(dp[u][j],dp[u][j-edge[i].w*2-k]+value[v]+dp[v][k]);
}
}
}
int main()
{
int n,T,i,u;
while(scanf("%d%d",&n,&T)!=-1)
{
init();
for(i=1;i<n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
for(i=1;i<=n;i++)
scanf("%d",&value[i]);
fa[1]=-1;
dfs(1,1);
int ans=0;
for(u=n;u!=1;u=fa[u])
{
ans+=edge[pre[u]].w;
edge[pre[u]].w=edge[pre[u]^1].w=0;
}
T-=ans;
if(T<0)
{
printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");
continue;
}
memset(dp,0,sizeof(dp));
dfs1(1,1,T);
printf("%d\n",dp[1][T]+value[1]);
}
}
树形DP(01组合背包The Ghost Blows Light HDU4276)的更多相关文章
- 【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 ...
- HDU 4276 The Ghost Blows Light
K - The Ghost Blows Light Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & ...
- BNUOJ 26283 The Ghost Blows Light
The Ghost Blows Light Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. O ...
- HDOJ 4276 The Ghost Blows Light(树形DP)
Problem Description My name is Hu Bayi, robing an ancient tomb in Tibet. The tomb consists of N room ...
- HDU-4661 Message Passing 树形DP,排列组合
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4661 题意:有n个人呈树状结构,每个人知道一个独特的消息.每次可以让一个人将他所知的所有消息告诉和他相 ...
- 树形DP+(分组背包||二叉树,一般树,森林之间的转换)codevs 1378 选课
codevs 1378 选课 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 学校实行学分制.每门的必修课都有固定的学分 ...
- CH5402 选课【树形DP】【背包】
5402 选课 0x50「动态规划」例题 描述 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了 N(N≤300) 门的选修课程,每个学生可选课程的数量 M 是 ...
- HDU 4276 The Ghost Blows Light(树形)
题意:给出一棵n个节点的树,起点1,终点n,相连的两个节点之间有距离,每个节点有个价值,给出一个时间T.问从1到达n在给定时间T内取得的最大价值? 思路:先从1走到n,如果总的时间不够走完,直接退出, ...
- HDOJ 4276 The Ghost Blows Light
题意 1. 给定一棵树, 树上节点有 value, 节点之间 travel 有 cost. 给定起始节点和最大 cost, 求解最大 value 思路 1. 寻找最短路径 a. 题目描述中有两句话, ...
随机推荐
- linux下线程调用sleep,进程挂起
http://blog.csdn.net/horstlinux/article/details/7911457 http://blog.csdn.net/eroswang/article/detail ...
- 通过驱动向打印机发送一段(ESC)控制指令
这个功能看起来挺奇葩的, 写这个是因为有客户在使用驱动连接票据打印机, 但是又要开钱箱, 驱动里只能每张单据都开钱箱, 而这个打印机又不是只打印结帐单 所以就需要用软件控制打印机开钱箱 票据打印机一般 ...
- 我的第一个chrome扩展(2)——基本知识
1.manifest介绍界面:json格式 json:JavaScript Object Notation 包括两种结构: key:value对:{{"A1":"valu ...
- 国家发改委发布的数据,前三季度我国生产的手机、PC、集成电路、宽带上网的数量
集微网消息,根据国家发改委发布的数据,前三季度,我国生产集成电路944亿块,同比增长18.2%. 此外,前三季度,生产手机15亿部,同比增长17.6%,其中智能手机11亿部,增长12.1%,占全部手机 ...
- 20145211 《Java程序设计》实验报告二:Java面向对象程序设计
实验要求 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验内容 单元测试 面向对象三要素 设计模式初步 练习 实 ...
- 算法训练 A+B Problem
算法训练 A+B Problem 时间限制:1.0s 内存限制:512.0MB 问题描述 输入A,B. 输出A+B. 输入格式 输入包含两个整数A,B,用一个空格分隔. 输出格式 ...
- [LeetCode]题解(python):050-Pow(x, n)
题目来源 https://leetcode.com/problems/powx-n/ Implement pow(x, n). 题意分析 Input: x,n Output:pow(x,n) Cond ...
- Swift-07-析构器deinit
析构器只适用于类类型,当一个类的实例被释放之前,析构器会被立即调用.析构器用关键字deinit来标识,类似于构造器用init来标识. 原理: Swift会自动释放不再需要的实例以释放资源.Swift通 ...
- boost.compressed_pair源码剖析
意义 当compressed_pair的某一个模板参数为一个空类的时候将对其进行“空基类优化”,这样可以使得compressed_pair占用的空间比std::pair的更小. 参考如下代码: #in ...
- C语言课本实例
1. 将一维数组的内容倒顺 #include <stdio.h>void func(int *s,int n){ int i,temp; for(i=0;i<n/2;i++) { t ...