题目:一棵树,每个结点上都有一些苹果,且相邻两个结点间的距离为1。一个人从根节点(编号为1)开始走,一共可以走k步,问最多可以吃多少苹果。

思路:这里给出数组的定义:

dp[0][x][j] 为从结点x开始走,一共走j步,且j步之后又回到x点时最多能吃到的苹果数。

dp[1][x][j] 为从结点x开始走,一共走j步最多能吃到的苹果数(不必再回到x点)。之所以要定义上面的一种状态是因为在求第二种状态时需要用到。

下面介绍递推公式。

对于结点x,假设它目前要访问的孩子为y,则1...(y-1)已经遍历过。此时有:

dp[0][x][j+2] = max(dp[0][x][j], dp[0][x][m] + dp[0][y][j-m])

注:dp[0][x][m]在每次dp后都会进行更新,此时的dp[0][x][m]实际上只是遍历过孩子结点1...(y-1)的情况。等号左边j之所以要加2是因为右面的总距离没有考虑从点x到y以及从y再回到x的距离,在这里要加上。

dp[1][x][j+1] = max(dp[1][x][j+1], dp[0][x][m] + dp[1][y][j-m])

注:遍历y结点,且不再回来。j加1表示只需要走一次从x到y的边。

dp[1][x][j+2] = max(dp[1][x][j+2], dp[1][x][m] + dp[0][y][j-m])

注:遍历y结点且又回到结点x,则必然是从1...(y-1)中的某个结点有去无回。

另外在dp的过程中,对于结点x的每个孩子都需要枚举走过的步数。而这个步数的枚举从小到大还是从大到小结果是不一样的。这就要看到前面递推公式里的定义,要求dp[0/1][x][m]存储的是遍历y前面的孩子结点的dp值。因此步数要从大到小枚举,这样每次值更新后都不会影响到下次dp。不然会wa。当然,也可以在每次dp前将dp[0/1][x][m]这两个值存储起来,这样就不用考虑这个问题了。

 #include<stdio.h>
#include<string.h>
#include<algorithm>
#define maxn 105
#define maxk 205
using namespace std;
int n, k;
int w[maxn];
bool vis[maxn];
struct node
{
int v, next;
}edge[maxn<<];
int num_edge, head[maxn];
void init_edge()
{
num_edge = ;
memset(head, -, sizeof(head));
}
void addedge(int a,int b)
{
edge[num_edge].v = b;
edge[num_edge].next = head[a];
head[a] = num_edge++;
}
int dp[][maxn][maxk];
void getdp(int x)
{
vis[x] = ;
for (int i = ; i <= k; i++)
dp[][x][i] = dp[][x][i] = w[x];
for (int i = head[x]; i != -; i = edge[i].next)
{
int v = edge[i].v;
if (vis[v]) continue;
getdp(v);
for (int j = k; j >= ; j--)
for (int m = ; m <= j; m++)
{
dp[][x][j+] = max(dp[][x][j+], dp[][x][m] + dp[][v][j-m]);
dp[][x][j+] = max(dp[][x][j+], dp[][x][m] + dp[][v][j-m]);
dp[][x][j+] = max(dp[][x][j+], dp[][x][m] + dp[][v][j-m]);
}
}
}
int main()
{
while (~scanf("%d%d",&n,&k))
{
init_edge();
memset(vis, , sizeof(vis));
for (int i = ; i <= n; i++)
scanf("%d",&w[i]);
for (int i = ; i < n; i++)
{
int a, b;
scanf("%d%d",&a,&b);
addedge(a, b);
addedge(b, a);
}
getdp();
printf("%d\n", dp[][][k]);
}
return ;
}

POJ 2486 Apple Tree [树状DP]的更多相关文章

  1. POJ 2486 Apple Tree ( 树型DP )

    #include <iostream> #include <cstring> #include <deque> using namespace std; #defi ...

  2. POJ 3321 Apple Tree(树状数组)

                                                              Apple Tree Time Limit: 2000MS   Memory Lim ...

  3. POJ 3321 Apple Tree (树状数组+dfs序)

    题目链接:http://poj.org/problem?id=3321 给你n个点,n-1条边,1为根节点.给你m条操作,C操作是将x点变反(1变0,0变1),Q操作是询问x节点以及它子树的值之和.初 ...

  4. POJ 3321 Apple Tree 树状数组+DFS

    题意:一棵苹果树有n个结点,编号从1到n,根结点永远是1.该树有n-1条树枝,每条树枝连接两个结点.已知苹果只会结在树的结点处,而且每个结点最多只能结1个苹果.初始时每个结点处都有1个苹果.树的主人接 ...

  5. POJ 3321 Apple Tree 树状数组 第一题

    第一次做树状数组,这个东西还是蛮神奇的,通过一个简单的C数组就可以表示出整个序列的值,并且可以用logN的复杂度进行改值与求和. 这道题目我根本不知道怎么和树状数组扯上的关系,刚开始我想直接按图来遍历 ...

  6. POJ 2486 Apple Tree(树形dp)

    http://poj.org/problem?id=2486 题意: 有n个点,每个点有一个权值,从1出发,走k步,最多能获得多少权值.(每个点只能获得一次) 思路: 从1点开始,往下dfs,对于每个 ...

  7. POJ 2486 Apple Tree (树形DP,树形背包)

    题意:给定一棵树图,一个人从点s出发,只能走K步,每个点都有一定数量的苹果,要求收集尽量多的苹果,输出最多苹果数. 思路: 既然是树,而且有限制k步,那么树形DP正好. 考虑1个点的情况:(1)可能在 ...

  8. poj2486--Apple Tree(树状dp)

    Apple Tree Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7789   Accepted: 2606 Descri ...

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

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

随机推荐

  1. Python 日常报错总结

    本章内容 requests模块报错 执行:res = requests.post(api,mdata = post_data) 报错:SSLError: EOF occurred in violati ...

  2. Python框架之Django学习笔记(四)

    第一个基于Django的页面:Hello World 正如我们的第一个目标,创建一个网页,用来输出这个著名的示例信息:Hello world. 第一个视图 Hello world视图非常简单. 这些是 ...

  3. Python实现对百度云的文件上传

    环境准备 python3.6 PyCharm 2017.1.3 Windows环境 框架搭建 selenium3.6 安装方法: pip install selenium 实现步骤: 一.步骤分析 1 ...

  4. Python-S9-Day88——stark组件之设计urls

    03 stark组件之设计urls 04 stark组件之设计urls2 05 stark组件之设计list_display 06 stark组件之z查看页面的数据展示 03 stark组件之设计ur ...

  5. Mac OS 添加 MySQL 环境变量

    1.打开终端,输入: cd ~ 会进入~文件夹 2.如果 ~ 文件夹中已经存在 .bash_profile 文件,则在 : 后面追加你想要添加的路径, 3. 否则输入:touch .bash_prof ...

  6. python 字符编码与转码

    一. 字符编码 ASCII: 一个字节,最多能表示255个字符 GB2312(1980年):一共收录了7445个字符,包括6763个汉字和682个其它符号. GBK1.0(1995年):收录了2188 ...

  7. Mybatis通过接口实现一对一及一对多的查询

    实现一对一是采用association方法: <resultMap type="testId" id="users"> <associatio ...

  8. 【距离GDOI:136天】 后缀数组中...

    当时后缀数组没有好好学...各种应用都没学,这两天好好补,要把罗神的论文好好研究一遍...其实后缀数组真的好神奇!!特别是那个萌萌的height数组! 今天终于能有两节完整的晚自修了QAQ...明晚还 ...

  9. 本文将介绍“数据计算”环节中常用的三种分布式计算组件——Hadoop、Storm以及Spark。

    本文将介绍“数据计算”环节中常用的三种分布式计算组件——Hadoop.Storm以及Spark. 当前的高性能PC机.中型机等机器在处理海量数据时,其计算能力.内存容量等指标都远远无法达到要求.在大数 ...

  10. web常见攻击总结

    1.Sql注入 攻击者把sql命令插入到web表单的输入域或页面请求的查询字符串, 欺骗服务器执行恶意的sql命令 防御措施 前端: 1.正则验证字符串格式 2.过滤字符串的非法字符 后端: 1.不要 ...