POJ 2486 Apple Tree [树状DP]
题目:一棵树,每个结点上都有一些苹果,且相邻两个结点间的距离为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]的更多相关文章
- POJ 2486 Apple Tree ( 树型DP )
#include <iostream> #include <cstring> #include <deque> using namespace std; #defi ...
- POJ 3321 Apple Tree(树状数组)
Apple Tree Time Limit: 2000MS Memory Lim ...
- POJ 3321 Apple Tree (树状数组+dfs序)
题目链接:http://poj.org/problem?id=3321 给你n个点,n-1条边,1为根节点.给你m条操作,C操作是将x点变反(1变0,0变1),Q操作是询问x节点以及它子树的值之和.初 ...
- POJ 3321 Apple Tree 树状数组+DFS
题意:一棵苹果树有n个结点,编号从1到n,根结点永远是1.该树有n-1条树枝,每条树枝连接两个结点.已知苹果只会结在树的结点处,而且每个结点最多只能结1个苹果.初始时每个结点处都有1个苹果.树的主人接 ...
- POJ 3321 Apple Tree 树状数组 第一题
第一次做树状数组,这个东西还是蛮神奇的,通过一个简单的C数组就可以表示出整个序列的值,并且可以用logN的复杂度进行改值与求和. 这道题目我根本不知道怎么和树状数组扯上的关系,刚开始我想直接按图来遍历 ...
- POJ 2486 Apple Tree(树形dp)
http://poj.org/problem?id=2486 题意: 有n个点,每个点有一个权值,从1出发,走k步,最多能获得多少权值.(每个点只能获得一次) 思路: 从1点开始,往下dfs,对于每个 ...
- POJ 2486 Apple Tree (树形DP,树形背包)
题意:给定一棵树图,一个人从点s出发,只能走K步,每个点都有一定数量的苹果,要求收集尽量多的苹果,输出最多苹果数. 思路: 既然是树,而且有限制k步,那么树形DP正好. 考虑1个点的情况:(1)可能在 ...
- poj2486--Apple Tree(树状dp)
Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7789 Accepted: 2606 Descri ...
- poj 2486 Apple Tree(树形DP 状态方程有点难想)
Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9808 Accepted: 3260 Descri ...
随机推荐
- Go语言之并发编程(二)
通道(channel) 单纯地将函数并发执行是没有意义的.函数与函数间需要交换数据才能体现并发执行函数的意义.虽然可以使用共享内存进行数据交换,但是共享内存在不同的goroutine中容易发生竞态问题 ...
- java对象转json格式
package com; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import jav ...
- 【palindrome partitioning II】cpp
题目: Given a string s, partition s such that every substring of the partition is a palindrome. Return ...
- centOS如何设置时间同步
1.进入系统-管理-时间和日期 2.这个需要root权限才能进行设置,在弹出框中填入root密码 3.设置时间和日期-勾选同步,并且选择NTP时间服务器,点击确定 4.选择时区为亚洲上海点击保存 ...
- linux环境搭建系列之maven
前提: jdk1.7 Linux centOS 64位 安装包从官网获取地址:http://maven.apache.org/download.cgi Jdk1.7对应apache-maven-3.3 ...
- bat 处理adb脚本
@echo off REM Funtion: 测试parsermode 接口CdxParserGetMediaInfo 和CdxParserRead REM Code by lzp 2017-05-0 ...
- 链表的问题,ListNode问题
算法面试,有关ListNode的问题 class ListNode{ ListNode *next; int val; ListNode(int x): val(x){}}; 在面试的时候,怎么快速想 ...
- 【转】Unity5.x发布IOS项目Xcode8免签证调试发布教程
http://www.jianshu.com/p/b0fb49fbcc14 最近尝试发布一下IOS项目,发现现在发布已经简单很多了,不需要开发者账户也能简单快捷进行真机调试. 调试: 1.准备工作①硬 ...
- 重绘(repaints)与重排(reflows)
当页面布局和几何属性改变时就需要"重排" 避免在修改样式的过程中使用 offsetTop, scrollTop, clientTop, getComputedStyle() 这些属性, 它们都会刷新渲 ...
- Java面试题之在多线程情况下,单例模式中懒汉和饿汉会有什么问题呢?
懒汉模式和饿汉模式: public class Demo { //private static Single single = new Single();//饿汉模式 private static S ...