题目:一棵树,每个结点上都有一些苹果,且相邻两个结点间的距离为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. Unity脚本执行顺序自研框架

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/52372611 作者:car ...

  2. MongoDB快速入门学习笔记6 MongoDB的文档删除操作

    db.集合名称.remove({query}, justOne)query:过滤条件,可选justOne:是否只删除查询到的第一条数据,值为true或者1时,只删除一条数据,默认为false,可选. ...

  3. RSA进阶之两个N的公约数

    适用场景: 给你两个n,n1和n2. 两个数都很大,不好分解. 但是这数刚好有质数公因子(试试欧几里得辗转相除跑完之后,就是不断地相除就可以了,4000多位也是很快的),那不就相当于间接的分解出q或者 ...

  4. xss games20关小游戏附源代码

    1. get方式的的值直接输出来了. ?name=<script>alert(1)</script> 2. 同样没有过滤,不过需要闭合前边的双引号和>. "&g ...

  5. STL之vector使用简介

    Vector成员函数 函数 表述 c.assign(beg,end)c.assign(n,elem) 将[beg; end)区间中的数据赋值给c.将n个elem的拷贝赋值给c. c.at(idx) 传 ...

  6. Python面向对象之什么是类(1)

    1.C#.Java :只能用面向对象编程 Ruby.Python :函数编程+ 面向对象 面向对象编程不是在所有地方都比函数式编程方便的,类是为了封装,下面是简单的使用方法 在创建类的时候要用clas ...

  7. web访问流程

    客户端发送请求—->httpd得到请求—->httpd解析请求的格式(html,css,jsp)—->请求相应的PHP解析—->PHP解析程序执行完毕—–>db(数据库) ...

  8. 详解 MySQL 的计划任务

    注意:5.1以后才支持! 让MYSQL定期执行指定的一条命令.功能类似于crontab. 1. 检查你的MYSQL是否开了这个功能 SHOW VARIABLES LIKE 'event_schedul ...

  9. 多IP指定出口IP地址 如何指定云服务器源IP?

    如果一个主机绑定有多个IP地址,那么在被动响应和主动发起连接两种方式中,源IP地址的选择机制肯定是有所差异的.主机在接收外部数据包,并发送响应数据包时,响应源地址显然就是客户端请求的地址,这是非常容易 ...

  10. 通过sql查询rman备份信息

    通过sql查询rman备份信息 查看所有备份集 SELECT A.RECID "BACKUP SET", A.SET_STAMP, DECODE (B.INCREMENTAL_LE ...