http://blog.csdn.net/dellaserss/article/details/8799730

这题其实和上一题思路是一样的,一个0节点作为根节点,通过剩余量来遍历子树。

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std; #define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define MAXN 205
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pqueue priority_queue
#define INF 0x3f3f3f3f int n,m; struct node
{
int y,next;
}tree[]; int head[MAXN],dp[MAXN][MAXN],ptr=; int sum[MAXN],vl[MAXN],vis[MAXN]; void add(int x,int y)
{
tree[ptr].y = y;
tree[ptr].next = head[x];
head[x] = ptr++;
} void dfs(int root)
{
if(vis[root]) return;
int i,j,k;
vis[root] = sum[root] = ;
int tot = ; for(i=head[root]; i!=-; i=tree[i].next)
{
int p = tree[i].y; if(!vis[p])
{
dfs(p);
sum[root]+=sum[p];
tot++;
//pf("i%d p%d tot%d sum%d\n",root,p,tot,sum[root]);
}
} dp[root][] = vl[root]; for(i=head[root]; i!=-; i=tree[i].next)
{
int p = tree[i].y; for(j = sum[root];j>;j--)
{
for(k = ;k<j;k++)
{
if(dp[root][k]!=- && dp[p][j-k]!=-)
{
dp[root][j] = max(dp[root][j],dp[root][k]+dp[p][j-k]);
//pf("i%d j%d k%d p%d dp%d\n",root,j,k,p,dp[root][j]);
}
}
}
}
} int main()
{
int i,j,k,a,b;
while(~sf("%d%d",&n,&m) && m+n>)
{
mem(head,-);
ptr = ; for(i=;i<=n;i++)
{
sf("%d%d",&a,&b);
add(i,a);
add(a,i);
vl[i] = b;
}
mem(dp,-);
mem(vis,);
dfs();
pf("%d\n",dp[][m+]);
}
return ;
}

但我发现这道题因为要统计子节点数量,其实用邻接表更方便一些:(但速度会慢很多)

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std; #define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define MAXN 205
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pqueue priority_queue
#define INF 0x3f3f3f3f int n,m; struct node
{
int y,next;
}tree[]; int head[MAXN],dp[MAXN][MAXN],ptr=; int sum[MAXN],vl[MAXN],vis[MAXN]; vector<int> son[]; void dfs(int root)
{
int i,j,k; for(i=;i<son[root].size();i++)
{
int p = son[root][i]; if(son[p].size()>) dfs(p); for(j=m;j>;j--)
{
for(k=;k<j;k++)
{
dp[root][j] = max(dp[root][j],dp[root][k] + dp[p][j-k]);
//pf("i%d j%d k%d p%d dp%d\n",root,j,k,p,dp[root][j]);
}
}
}
} int main()
{
int i,j,k,a,b;
while(~sf("%d%d",&n,&m) && m+n>)
{
mem(dp,);
m++; for(i=;i<=n;i++) son[i].clear(); for(i=;i<=n;i++)
{
sf("%d%d",&a,&b);
son[a].pb(i);
for(j=;j<=m;j++) dp[i][j] = b;
}
dfs();
pf("%d\n",dp[][m]);
}
return ;
}

hdu 1561 树形背包 选k个最大价值的更多相关文章

  1. HDU 1011 树形背包(DP) Starship Troopers

    题目链接:  HDU 1011 树形背包(DP) Starship Troopers 题意:  地图中有一些房间, 每个房间有一定的bugs和得到brains的可能性值, 一个人带领m支军队从入口(房 ...

  2. HDU 1561 (树形DP+背包)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1561 题目大意:从树根开始取点.最多取m个点,问最大价值. 解题思路: cost=1的树形背包. 有 ...

  3. HDU 1561 树形DP(入门)

    题目链接:  HDU 1561 The more, The Better #include <iostream> #include <cstdio> #include < ...

  4. hdu 1561 树形dp+分组背包

    题意:就是给定n个点,每个地点有value[i]的宝物,而且有的宝物必须是另一个宝物取了才能取,问取m个点可以获得的最多宝物价值. 一个子节点就可以返回m个状态,每个状态表示容量为j(j<=m) ...

  5. hdu 1561 树形DP n个选m个价值最大

    http://acm.hust.edu.cn/vjudge/problem/18068 #include <iostream> #include <string> #inclu ...

  6. hdu 1561(树形dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 思路:dp[u][i]表示以u为根的树选了i个子节点. #include<iostream ...

  7. HDU 1561 树形DP入门

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  8. HDU 1561 树形DP背包问题

    这是自己第一道背包上树形结构问题,不是很理解这个概念的可以先看看背包九讲 自己第一次做,看了一下别人的思路,结合着对简单背包问题的求解方式自己一次AC了还是有点小激动的 题目大意是: 攻克m个城市,每 ...

  9. HDU 2639(01背包第K大)

    http://acm.hdu.edu.cn/showproblem.php?pid=2639 http://blog.csdn.net/lulipeng_cpp/article/details/758 ...

随机推荐

  1. 洛谷P4548 [CTSC2006]歌唱王国(概率生成函数)

    题面 传送门 给定一个长度为\(L\)的序列\(A\).然后每次掷一个标有\(1\)到\(m\)的公平骰子并将其上的数字加入到初始为空的序列\(B\)的末尾,如果序列B中已经出现了给定序列\(A\), ...

  2. Ionic开发Hybrid App问题总结

    http://ionichina.com/topic/5641b891b903cba630e25f10 http://www.cnblogs.com/parry/p/issues_about_buil ...

  3. ARC初步介绍

    [转载自 http://onevcat.com/2012/06/arc-hand-by-hand/] 手把手教你ARC——iOS/Mac开发ARC入门和使用 Revolution of Objecti ...

  4. 如何调用另一个包中的Application

    在项目中要集成Xabber,将它作为一个Lib, ..... Xabber 原有代码 /** * Base entry point. * * @author alexander.ivanov */ p ...

  5. 欧拉筛(线性筛) & 洛谷 P3383 【模板】线性筛素数

    嗯.... 埃氏筛和欧拉筛的思想都是相似的: 如果一个数是素数,那么它的所有倍数都不是素数.... 这里主要介绍一下欧拉筛的思路:(欧拉筛的复杂度大约在O(n)左右... 定义一个prime数组,这个 ...

  6. js 时间戳的转化,js 日期转成标准字符串,日期格式的相互转化

    1.时间的获取 var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份(4位,1 ...

  7. 04. prosition 的值都有哪些,其最本质的区别在哪里?

    4.prosition 的值都有哪些,其最本质的区别在哪里? position:relative 相对定位 position:fixed 相对浏览器定位 position:absolute 绝对定位 ...

  8. JQuery.Validate学习笔记

    JQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆绑了一套有用的验证方法,包括 URL 和电子邮件验证 ...

  9. 时间超限问题处理(c++)

    c++中 如果时间超上限 做题上: 考虑关于二进制的方法 比如说 find your present (2) 这道题 可以用异或运算 来发现不重复数 对于动态规划 状态压缩发面 方面应用更多 比如说p ...

  10. 剑指offer——面试题17:打印从1到最大的n位数

    用字符串模拟加法: #include"iostream" #include"string.h" using namespace std; bool AddOne ...