hdoj4276(树形dp+分组背包)
题目链接:https://vjudge.net/problem/HDU-4276
题意:给出一棵树,起点为1,时间为V,终点为n,每个点有一个价值a[u],每条边有一个时间花费w,求在时间V内到达终点n可以获得的最大价值。
思路:
考虑边有两种情况,一种是属于1->n路径上的(只用走一次),一种是不属于该路径上的(需要走两次),为了统一,不妨把V减去1-n路径上的权值和,然后把1->n路径上边的权值置为0。
此时就转换为求在起点1,在时间V内回到起点的最大价值。用dp[u][j]表示在点u有时间j,最后回到点u的最大价值,dp[u][j]初始化为a[u](0<=j<=V),转移方程为:
dp[u][j]=max(dp[u][j],dp[u][j-tmp-k]+dp[v][k]。
其中v为u的子结点,tmp=2×w(u,v)。
AC代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; int n,V,a[],e[][],dp1[],dp2[][]; void dfs1(int u,int fa){
dp1[u]=-;
if(u==n) dp1[u]=;
for(int i=;i<=n;++i)
if(e[u][i]!=-){
if(i==fa) continue;
dfs1(i,u);
if(dp1[i]!=-){
dp1[u]=dp1[i]+e[u][i];
e[u][i]=e[i][u]=;
}
}
} void dfs2(int u,int fa){
for(int j=;j<=V;++j)
dp2[u][j]=a[u];
for(int i=;i<=n;++i)
if(e[u][i]!=-){
if(i==fa) continue;
dfs2(i,u);
int tmp=*e[u][i];
for(int j=V;j>=tmp;--j)
for(int k=;k<=j-tmp;++k)
dp2[u][j]=max(dp2[u][j],dp2[u][j-tmp-k]+dp2[i][k]);
}
} int main(){
while(~scanf("%d%d",&n,&V)){
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
e[i][j]=-;
for(int i=;i<n;++i){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
e[u][v]=e[v][u]=w;
}
for(int i=;i<=n;++i)
scanf("%d",&a[i]);
dfs1(,);
if(V<dp1[]){
printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");
continue;
}
V-=dp1[];
dfs2(,);
printf("%d\n",dp2[][V]);
}
return ;
}
hdoj4276(树形dp+分组背包)的更多相关文章
- HDU4003Find Metal Mineral[树形DP 分组背包]
Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Other ...
- HDU-1011 Starship Troopers (树形DP+分组背包)
题目大意:给一棵有根带点权树,并且给出容量.求在不超过容量下的最大权值.前提是选完父节点才能选子节点. 题目分析:树上的分组背包. ps:特判m为0时的情况. 代码如下: # include<i ...
- Ural-1018 Binary Apple Tree(树形dp+分组背包)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #i ...
- hdu 1561 树形dp+分组背包
题意:就是给定n个点,每个地点有value[i]的宝物,而且有的宝物必须是另一个宝物取了才能取,问取m个点可以获得的最多宝物价值. 一个子节点就可以返回m个状态,每个状态表示容量为j(j<=m) ...
- 【P2015】二叉苹果树 (树形DP分组背包)
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 现在这颗树枝条太多了,需要剪枝.但是 ...
- poj2486 Apple Tree (树形dp+分组背包)
题目链接:https://vjudge.net/problem/POJ-2486 题意:一棵点权树,起点在1,求最多经过m条边的最大点权和. 思路: 树形dp经典题.用3维状态,dp[u][j][0/ ...
- hdu1561 The more, The Better 树形DP+分组背包
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 思路: 典型的树形背包题目: 定义dp[i][j]表示以i为根节点,攻打j个城堡的获得的财宝的最 ...
- hdu 4003 树形dp+分组背包 2011大连赛区网络赛C
题意:求K个机器人从同一点出发,遍历所有点所需的最小花费 链接:点我 Sample Input 3 1 1 //3个点,从1出发,1个机器人 1 2 1 1 3 1 3 1 2 1 2 1 1 3 1 ...
- HDU-4003 Find Metal Mineral (树形DP+分组背包)
题目大意:用m个机器人去遍历有n个节点的有根树,边权代表一个机器人通过这条边的代价,求最小代价. 题目分析:定义状态dp(root,k)表示最终遍历完成后以root为根节点的子树中有k个机器人时产生的 ...
随机推荐
- vue中把props中的值赋值给data
vue中把props中的值赋值给data 2018年12月26日 14:37:11 木豆mudou 阅读数 3497 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上 ...
- SharePoint學習
1.SharePoint 2010 Products -> SharePoint 2010 Products Configuration Wizard 配置好后,系統會自動在localho ...
- 参数类型 (@Service层) impl
@Override public List<Map<String, Object>> selectAdvListByPosition(String adStructure, P ...
- Visual Studio Code:以十六进制格式显示文件内容
造冰箱的大熊猫@cnblogs 2019/9/4 发现Visual Studio Code很好用,无论是作为源代码编辑器还是文本编辑器在Win平台下用的都很不错.但有时候需要以十六进制格式查看数据文件 ...
- linux系统编程--线程同步
同步概念 所谓同步,即同时起步,协调一致.不同的对象,对“同步”的理解方式略有不同. 如,设备同步,是指在两个设备之间规定一个共同的时间参考: 数据库同步,是指让两个或多个数据库内容保持一致,或者按需 ...
- background-size值为cover和值为100%的区别
background-size:100% 100%;---按容器比例撑满,图片变形: background-size:cover;---把背景图片放大到适合元素容器的尺寸,图片比例不变. IE8及以下 ...
- mkswap/swapon/swapoff/free
free mkswap 创建Linux交换分区 swapon 启用交换分区 swapoff 关闭交换分区 注意: 在创建完交换区之后.是需要激活才能使用的 swapon/swapoff
- leetcode解题报告(8):Remove Element
描述 Given an array and a value, remove all instances of that value in place and return the new length ...
- 我终于搞清楚了和String有关的那点事儿。
String,是Java中除了基本数据类型以外,最为重要的一个类型了.很多人会认为他比较简单.但是和String有关的面试题有很多,下面我随便找两道面试题,看看你能不能都答对: Q1:String s ...
- Windows下的Jupyter Notebook 安装与自定义启动
1.Jupyter Notebook 和 pip 为了更加方便地写 Python 代码,还需要安装 Jupyter notebook. 利用 pip 安装 Jupyter notebook. 为什么要 ...