题目链接

输入:一棵树,每个节点一个权值。

输出:包括1号节点在内的m个节点组成的连通分量的权值和的最大值

hdu1561和hiho1055一样,只是变换了下说法

/**********************************************/

计 dp(i,j) 为以i为根的子树选中j个点(包括i)时的最大权值和。则dp(1,m)即为所求。

方程:

{

dp[i][0] = 0;

dp[i][1] = value[i];

foreach child c of i

for j = m...2

for k = 1...j-1

dp[i][j] = max(dp[i][j],dp[i][j-k]+dp[c][k])

}

因为dp的核心就是记忆化搜索,所以自下向上处理整棵树,处理完一个节点就标记一下,下次用到这个节点的时候就不用再递归了。

这里我用getCnt()函数计算了一下以每个节点i为根的子树中节点的数目cnt(i),为的是缩小求dp(i,j)中j和k的上限,由m变为MIN(m,cnt(i)),应该不会提速多少

#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> #define MAX(a,b) ((a)>=(b)?(a):(b))
#define MIN(a,b) ((a)<=(b)?(a):(b))
#define OO 0x0fffffff
using namespace std;
const int N = 111; struct Edge{
int to;
int next;
};
int eid = 0;
Edge edges[N*2];
int heads[N];
void addEdge(int a,int b){
edges[eid].to = a;
edges[eid].next = heads[b];
heads[b] = eid++; edges[eid].to = b;
edges[eid].next = heads[a];
heads[a] = eid++;
} int m,n;
int dp[N][N],cnt[N],visited[N]; void getCnt(int id){
visited[id] = 1;
for(int cur = heads[id];cur!=-1;cur=edges[cur].next){
int cid = edges[cur].to;
if(!visited[cid]) {
if(!cnt[cid]) getCnt(cid);
cnt[id] += cnt[cid];
}
}
cnt[id] += 1;
}
void traverse(int id){
visited[id] = 1;
for(int cur=heads[id];cur!=-1;cur=edges[cur].next){
int cid = edges[cur].to;
if(!visited[cid]){
if(!visited[cid]) traverse(cid);
for(int i=MIN(m,cnt[id]);i>=2;i--){
for(int j=1;j<MIN(i,cnt[cid]+1);j++){
dp[id][i]=MAX(dp[id][i],(dp[id][i-j]+dp[cid][j]));
}
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++) scanf("%d",dp[i]+1); int a,b;
memset(heads,-1,sizeof(heads));
for(int i=0;i<n-1;i++){
scanf("%d%d",&a,&b);
addEdge(a,b);
} memset(cnt,0,sizeof(cnt));
memset(visited,0,sizeof(visited));
getCnt(1); memset(visited,0,sizeof(visited));
traverse(1); printf("%d\n",dp[1][m]);
return 0;
}

hiho1055/hdu1561 - 树形dp转换成背包的更多相关文章

  1. hdu1561 树形dp,依赖背包

    多重背包是某个物品可以选择多次,要把对物品数的枚举放在对w枚举外面 分组背包是某组的物品只能选一个,要把对每组物品的枚举放在对w枚举内侧 依赖背包是多层的分组背包,利用树形结构建立依赖关系,每个结点都 ...

  2. 树形DP+(分组背包||二叉树,一般树,森林之间的转换)codevs 1378 选课

    codevs 1378 选课 时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond  题目描述 Description 学校实行学分制.每门的必修课都有固定的学分 ...

  3. CH5402 选课【树形DP】【背包】

    5402 选课 0x50「动态规划」例题 描述 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了 N(N≤300) 门的选修课程,每个学生可选课程的数量 M 是 ...

  4. hdu1561 树形dp + 背包

    #include<cstdio> #include<cstring> #include<iostream> #define INF 999999999 using ...

  5. hdu4003详解(树形dp+多组背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4003 Find Metal Mineral Time Limit: 2000/1000 MS (Jav ...

  6. UVA Live Archive 4015 Cave (树形dp,分组背包)

    和Heroes Of Might And Magic 相似,题目的询问是dp的一个副产物. 距离是不好表示成状态的,但是可以换一个角度想,如果知道了从一个点向子树走k个结点的最短距离, 那么就可以回答 ...

  7. Codevs1378选课[树形DP|两种做法(多叉转二叉|树形DP+分组背包)---(▼皿▼#)----^___^]

    题目描述 Description 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修 ...

  8. HD1561The more, The Better(树形DP+有依赖背包)

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

  9. 【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 ...

随机推荐

  1. ORA-16019 和 ORA-16018 错误的处理方法(转)

    一. ORA-16019 和 ORA-16018 错误产生描述 同事在修改归档目录,一不小心把参数设置错误了, 他设置的是log_archive_dest参数. 这个参数和默认log_archive_ ...

  2. Java高级——交通灯管理系统

    本方法模拟了现实生活中的交通信号灯的情况 1.先构建Road类,此类可以创建12个方向的路 代码如下: package com.springtie.traffic; import java.util. ...

  3. Hybrid混合开发中schema协议的使用与封装

    混合开发中JS与APP通信的实现原理: JS通过schema协议,传递参数和全局回调函数给APP端 APP执行完(如微信扫一扫)后,调用协议中传入的回调函数,在前端执行回调处理. 默认写法: < ...

  4. P2216 [HAOI2007]理想的正方形(二维RMQ)

    题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示a,b,n的值 第二行至 ...

  5. 详解循环神经网络(Recurrent Neural Network)

    本文结构: 模型 训练算法 基于 RNN 的语言模型例子 代码实现 1. 模型 和全连接网络的区别 更细致到向量级的连接图 为什么循环神经网络可以往前看任意多个输入值 循环神经网络种类繁多,今天只看最 ...

  6. 关于Java中equal函数和==的一些区别

    equal函数比较的到底是什么,很明显是比较的值,但是什么值?与==比较的堆中的内存地址不同,其比较的是对象的值,包括各个属性的值.我们在重新overriding此方法时首先要判断是否为同一对象,如果 ...

  7. 防范CSRF(二)

    在防范CSRF(一)中使用的是微软默认的设置.在信息安全中默认的往往是最危险的.因此可以考虑更改cookie中默认的名字. 更改默认操作在Global.asax中的Application_Start使 ...

  8. 进入docker 容器内命令

    docker exec :在运行的容器中执行命令 语法 docker exec [OPTIONS] CONTAINER COMMAND [ARG...] OPTIONS说明: -d :分离模式: 在后 ...

  9. [poj 2976] Dropping tests (分数规划 二分)

    原题: 传送门 题意: 给出n个a和b,让选出n-k个使得(sigma a[i])/(sigma b[i])最大 直接用分数规划.. code: //By Menteur_Hxy #include & ...

  10. 四、分布式 Git(未完待续)

    一.分布式工作流程 在 Git 中,每个开发者同时扮演着节点和集线器的角色——也就是说,每个开发者既可以将自己的代码贡献到其他的仓库中,同时也能维护自己的公开仓库,让其他人可以在其基础上工作并贡献代码 ...