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. MIT 黑科技:通过脑电波和手势控制机器人

    简评:麻省理工黑科技,虽然现在能实现的操作还很简单,但前景(想象空间)非常巨大. 通常,控制机器人并不容易,常规手段就是编程.但是地球上从来不缺天马行空的科学家,今日 MIT 的计算机科学与人工智能实 ...

  2. 2019.2.14 t2 程序调试

    代码: #include <cstdio> #include <iostream> #include <cstring> #include <algorith ...

  3. 吃奶酪 状压dp

    题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入输出格式 输入格式: 第一行一个数n (n<=15) 接下来每行2个实数,表示第i块 ...

  4. 批量自动化生成PDF目录标签

    所需软件: 1. FreePic2Pdf(网上很容易找到) 2. python3 3. 天若OCR 链接:https://pan.baidu.com/s/1B9dUr3gc0pv0BSHo5QYGsQ ...

  5. [LnOI2019]加特林轮盘赌

    Luogu5249 轮流开枪打一个环上的人 , 每次\(p\)的概率打死 , \(p\)始终相同 , 从第\(1\)个人开始 , 求第\(k\)个人成为唯一幸存者的概率 \(19.3.30\) 官方题 ...

  6. POJ_3368 Frequent values 【线段树+区间查询】

    一.题面 POJ3368 二.分析 仍然是一道只需要区间查询不需要区间修改的线段树题. 这题的题面比较特别,它是一组非减的数组.当需要去找一段区间内出现次数最多的数字时,这些数字必然是连续的,那么就可 ...

  7. C. Ayoub and Lost Array Round #533 (Div. 2) 【DP】

    一.题面 链接 二.分析 关于这题,两个点. 第一个点,是需要能够分析出$[L,R]$区间的3的余数的个数. 首先,可以得到,$[L,R]$区间内共有$(R-L+1)$个数. 设定余数为0,1,2的为 ...

  8. [短期持续更新]Codeforces 构造题一览

    说实话我觉得做这种题很没意思(不够硬核), 可是人有短板终究是要补的...起码这种类型补起来相对简单 所以还是把先前准备好的专题放下吧,做点实现上比较休闲的题 ps.为了精简篇幅,代码全部丢到ubun ...

  9. 本科生毕业论文->计算机类(1)

    写在前面:作为一个计算机类学生,本文只是面向计算机类本科论文进行了一些小经验总结,每个学校的论文要求不一致,具体的参考规范可以看学校的通知,毕业论文作为毕业的一个重要审核标准,写好毕业论文是非常重要的 ...

  10. Python+Selenium之常用模块

    要用webdriver:from selenium import webdriver eg: driver = webdriver.Chrome()      driver.maximize_wind ...