HDU 1561 树形DP背包问题
这是自己第一道背包上树形结构问题,不是很理解这个概念的可以先看看背包九讲
自己第一次做,看了一下别人的思路,结合着对简单背包问题的求解方式自己一次AC了还是有点小激动的
题目大意是:
攻克m个城市,每个城市都有对应数量的宝贝,攻克某一个城市必须保证其对应的某一个特定城市已经被攻克,希望得到最多数量的宝贝
很容易根据题目画出一个对应关系的树形结构,每个节点都有一个对应的宝物的数量
我们用dp[i][j]存 i 号节点它下方子树中 有 j 个城市被攻克时得到的宝物最大数量 , 此时的 i 号是没有被攻克的!
然后通过dfs自底向上更新
/*
总的u下方子树攻克了j个城市,为当前v姿势分配k个城市攻克
添加当前v包含了攻克k-1个子树的城市,要添加子树v必须
同时保证v被攻克,所以加上的是dp[v][k-1] + val[v]
*/
for(int j = m ; j>= ; j--){
for(int k = j ; k> ; k--){
dp[u][j] = max(dp[u][j] , dp[u][j-k] + dp[v][k-] + val[v]);
}
}
这里可以理解为当根节点u下方有 j 个城市被攻克时, 若有 k 个城市的攻克来自v的子树, 那么v必然要被攻克 , val[v],不然其下方的城市不能攻克
除去v还有 k -1个v节点对应子树中的城市要攻克 ,也就是 dp[v][k-1]
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N = ; int dp[N][N] , val[N] , first[N] , k; struct Edge{
int y , next;
}e[N]; void add_edge(int x , int y)
{
e[k].y = y , e[k].next = first[x];
first[x] = k++;
} void dfs(int u , int m)
{
for(int i=first[u] ; i!=- ; i=e[i].next){
int v = e[i].y;
dfs(v , m);
/*
总的u下方子树攻克了j个城市,为当前v姿势分配k个城市攻克
添加当前v包含了攻克k-1个子树的城市,要添加子树v必须
同时保证v被攻克,所以加上的是dp[v][k-1] + val[v]
*/
for(int j = m ; j>= ; j--){
for(int k = j ; k> ; k--){
dp[u][j] = max(dp[u][j] , dp[u][j-k] + dp[v][k-] + val[v]);
}
}
}
} int main()
{
// freopen("a.in" , "r" , stdin);
int n , m , a , b;
while(scanf("%d%d" , &n , &m) , n||m)
{
memset(first , - , sizeof(first));
k = ;
for(int i= ; i<=n ; i++)
{
scanf("%d%d" , &a , &b);
add_edge(a , i);
val[i] = b;
}
memset(dp , , sizeof(dp));
dfs( , m); printf("%d\n" , dp[][m]);
}
return ;
}
HDU 1561 树形DP背包问题的更多相关文章
- HDU 1561 树形DP入门
The more, The Better Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- HDU 1561 树形DP(入门)
题目链接: HDU 1561 The more, The Better #include <iostream> #include <cstdio> #include < ...
- HDU 1561 (树形DP+背包)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1561 题目大意:从树根开始取点.最多取m个点,问最大价值. 解题思路: cost=1的树形背包. 有 ...
- hdu 1561(树形dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 思路:dp[u][i]表示以u为根的树选了i个子节点. #include<iostream ...
- hdu 1561 树形dp+分组背包
题意:就是给定n个点,每个地点有value[i]的宝物,而且有的宝物必须是另一个宝物取了才能取,问取m个点可以获得的最多宝物价值. 一个子节点就可以返回m个状态,每个状态表示容量为j(j<=m) ...
- hdu 1561 树形DP n个选m个价值最大
http://acm.hust.edu.cn/vjudge/problem/18068 #include <iostream> #include <string> #inclu ...
- hdu 4123 树形DP+RMQ
http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...
- HDU 1520 树形dp裸题
1.HDU 1520 Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> ...
- HDU 2196树形DP(2个方向)
HDU 2196 [题目链接]HDU 2196 [题目类型]树形DP(2个方向) &题意: 题意是求树中每个点到所有叶子节点的距离的最大值是多少. &题解: 2次dfs,先把子树的最大 ...
随机推荐
- sql server 触发器详细应用
SQL Server 触发器 触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发 ...
- hdu6195 cable cable cable
cable cable cable Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- CentOS6.5磁盘分区和挂载操作记录
CentOS6.5磁盘分区和挂载操作记录. [root@CentOS ~]# fdisk -l Disk /dev/sda: bytes heads, sectors/track, cylinders ...
- D. Fedor and coupons 二分暴力
http://codeforces.com/contest/754/problem/D 给出n条线段,选出k条,使得他们的公共部分长度最大. 公共部分的长度,可以二分出来,为val.那么怎么判断有k条 ...
- [转]MySQL存储过程
转自:http://www.cnblogs.com/exmyth/p/3303470.html 14.1.1 创建存储过程 MySQL中,创建存储过程的基本形式如下: CREATE PROCEDURE ...
- JOptionPane.showMessageDialog出现在浏览器下面的解决方法
将JOptionPane.showMessageDialog(null, result, "发布公告:", JOptionPane.INFORMATION_MESSAGE);中的参 ...
- 神奇的Object.defineProperty
vue.js和avalon.js 都是通过它实现双向绑定的. 对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值.定义对象可以使用构造函数或字面量的形式: var obj={}; o ...
- 【转】WITH AS 用法
转载自:http://blog.csdn.net/shaochao14/article/details/6223052 一.WITH AS的含义 WITH AS短语,也叫做子查询部分(subquery ...
- 第一节:EasyUI样式,行内编辑,基础知识
一丶常用属性 $('#j_dg_left').datagrid({ url: '/Stu_Areas/Stu/GradeList', fit: true, // 自动适应父容器大小 singleSel ...
- luogu P3899 [湖南集训]谈笑风生 线段树合并
Code: #include<bits/stdc++.h> #define maxn 300002 #define ll long long using namespace std; vo ...