题目链接:https://vjudge.net/problem/POJ-2486

题意:一棵点权树,起点在1,求最多经过m条边的最大点权和。

思路:

  树形dp经典题。用3维状态,dp[u][j][0/1]表示在子树u中走j步的最大价值(回到u/不回到u)。显然dp[u][j][1]>=dp[u][j][0],所以dp[1][m][1]就是最终答案。

  假设v为u的子结点,k为到v且在v中所用步数,那么转移方程分3步,为:

    dp[u][j][0]=max(dp[u][j][0] , dp[u][j-k][0]+dp[v][k-2][0]) (k>=2)

    dp[u][j][1]=max(dp[u][j][1] , dp[u][j-k][0]+dp[v][k-1][1]) (k>=1)

    dp[u][j][1]=max(dp[u][j][1] , dp[u][j-k][1]+dp[v][k-2][0]) (k>=2)  (第3步容易忘掉)

AC代码:

#include<cstdio>
#include<algorithm>
using namespace std; const int maxn=;
const int maxm=;
int n,m,cnt,a[maxn],head[maxn],dp[maxn][maxm][]; struct node{
int v,nex;
}edge[maxn<<]; void adde(int u,int v){
edge[++cnt].v=v;
edge[cnt].nex=head[u];
head[u]=cnt;
} void dfs(int u,int fa){
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v;
if(v==fa) continue;
dfs(v,u);
for(int j=m;j>=;--j)
for(int k=;k<=j;++k){
if(k>=) dp[u][j][]=max(dp[u][j][],dp[u][j-k][]+dp[v][k-][]);
if(k>=) dp[u][j][]=max(dp[u][j][],dp[u][j-k][]+dp[v][k-][]);
if(k>=) dp[u][j][]=max(dp[u][j][],dp[u][j-k][]+dp[v][k-][]);
}
}
} int main(){
while(~scanf("%d%d",&n,&m)){
cnt=;
for(int i=;i<=n;++i)
scanf("%d",&a[i]);
for(int i=;i<=n;++i){
head[i]=;
for(int j=;j<=m;++j)
dp[i][j][]=dp[i][j][]=a[i];
}
for(int i=;i<n;++i){
int u,v;
scanf("%d%d",&u,&v);
adde(u,v);
adde(v,u);
}
dfs(,);
printf("%d\n",dp[][m][]);
}
return ;
}

poj2486 Apple Tree (树形dp+分组背包)的更多相关文章

  1. Ural-1018 Binary Apple Tree(树形dp+分组背包)

    #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #i ...

  2. POJ2486 - Apple Tree(树形DP)

    题目大意 给定一棵n个结点的树,每个结点上有一定数量的苹果,你可以从结点1开始走k步(从某个结点走到相邻的结点算一步),经过的结点上的苹果都可以吃掉,问你最多能够吃到多少苹果? 题解 蛋疼的问题就是可 ...

  3. URAL_1018 Binary Apple Tree 树形DP+背包

    这个题目给定一棵树,以及树的每个树枝的苹果数量,要求在保留K个树枝的情况下最多能保留多少个苹果 一看就觉得是个树形DP,然后想出 dp[i][j]来表示第i个节点保留j个树枝的最大苹果数,但是在树形过 ...

  4. HDU4003Find Metal Mineral[树形DP 分组背包]

    Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Other ...

  5. POJ 2486 Apple Tree(树形DP)

    题目链接 树形DP很弱啊,开始看题,觉得貌似挺简单的,然后发现貌似还可以往回走...然后就不知道怎么做了... 看看了题解http://www.cnblogs.com/wuyiqi/archive/2 ...

  6. HDU-1011 Starship Troopers (树形DP+分组背包)

    题目大意:给一棵有根带点权树,并且给出容量.求在不超过容量下的最大权值.前提是选完父节点才能选子节点. 题目分析:树上的分组背包. ps:特判m为0时的情况. 代码如下: # include<i ...

  7. 【POJ 2486】 Apple Tree (树形DP)

    Apple Tree Description Wshxzt is a lovely girl. She likes apple very much. One day HX takes her to a ...

  8. poj 2486 Apple Tree(树形DP 状态方程有点难想)

    Apple Tree Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9808   Accepted: 3260 Descri ...

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

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

随机推荐

  1. 使用std::function改善模板的低效性

    泛型编程中,模板会根据传入类型的不同,生成多种实例,相对低效. 模板编程: #include <iostream> using namespace std; //未使用函数包装器 temp ...

  2. python3 操作ppt

    # pip install pywin32com# ppt太大会读取失败import win32com from win32com.client import Dispatch, constants ...

  3. JS 时间转换函数 字符串时间转换毫秒(互转)

    字符串转化为日期 let util = function(){ Date.prototype.Format = function(fmt) { var o = { "M+" : t ...

  4. 微信小程序之简单记账本开发记录(一)

    下载并安装微信开发者工具 在选择开发记账本程序的时候犹豫着选择android studio还是微信小程序 最后选择了微信小程序,因其便利和快捷. 话不多说,第一步,下载并安装微信开发者工具.下面是教程 ...

  5. Docker安装redis3.2

    1.拉取redis3.2镜像 2.使用docker images查看拉去下来的镜像 3.运行容器,命令如下 docker run -p : -v $PWD/data:/data -d redis:3. ...

  6. Golang字符串处理以及文件操作

    一.整数 1.int与uint的初值比较以及其大小. 1 /* 2 #!/usr/bin/env gorun 3 @author :xxxx 4 Blog:http://www.cnblogs.com ...

  7. 在Ubuntu上安装Qt5.2.0

    分类: QT2013-12-16 14:44 3171人阅读 评论(0) 收藏 举报 QT官方站点的文档有点老.今天,我尝试着在我的Ubuntu 13.10上安装Qt 5.2.0.下面是我的步骤: 1 ...

  8. JAVA基于File的基本的增删改查

    直接上代码 public class TestFile { /** * 创建目录 * @param filename 路径 */ public static void createFile(Strin ...

  9. 【Python】对我自己的博客进行统计,看看哪年哪月发帖量最大

    代码很简单,主要利用了requests进行网络访问,beautifulSoup进行页面文本分析,re进行正则表达式抽取文字,前面两个需要pip install name去安装,后者是内部对象所以不用安 ...

  10. c++拷贝文件-传统处理异常(学习)

    #include <iostream>#include <stdio.h> using namespace std; int my_copy(const char* src_f ...