Apple Tree POJ - 2486

题目大意:一棵点带权有根树,根节点为1。从根节点出发,走k步,求能收集的最大权值和。

树形dp。复杂度可能是O(玄学),不会超过$O(nk^2)$。(反正这题不卡这个,考思想)参考

ans[i][j][0]表示i点以下共走j步,不回来,可能收集到最大的权值
ans[i][j][1]表示i点以下共走j步,回来,可能收集到最大的权值

比较复杂的是,每个节点(以下称当前节点)从其子节点转移的时候,需要用一个背包:

t[i][j][0]表示当前节点的前i个子节点共走j步,不回来
t[i][j][1]表示当前节点的前i个子节点共走j步,回来

对于t[i][j][0],要么是当前节点的前i-1个子节点共走j步(包括去和回来前面的子节点所用步数),在之前就不回来;

要么是前i-1个子节点共走j-p步(包括去和回来前面的子节点所用步数),当前节点走到第i个子节点用1步,第i个子节点向下走p-1步,不回来;

要么是花一步走到第i个子节点,在第i个子节点往下走p-2步,再花一步走回当前节点,再在前i-1个子节点中走j-p步(包括去和回来前面的子节点所用步数)并且不回来。

因此t[i][j][0]=max(t[i-1][j][0],max{t[i-1][j-p][1]+ans[nowson][p-1][0]},max{t[i-1][j-p][0]+ans[nowson][p-2][1]})

对于t[i][j][1],要么是前i-1个子节点共走j-p步(包括去和回来前面的子节点所用步数),走到第i个子节点花1步,第i个子节点向下走用p-2步并回来,从第i个子节点回来花一步;要么是前i-1个子节点共走j步(包括去和回来前面的子节点所用步数),回来。

因此t[i][j][1]=max(t[i-1][j][1],max{t[i-1][j-p][1]+ans[nowson][p-2][1]})

当然实际求解的时候并不需要每个节点开一个t数组,只需要在ans数组上直接做就行了。就是先对t数组求解过程用滚动数组优化,那么只需要两维t[j][0/1]。这时只需要把ans[当前节点]的数组当做t去做就行了。另外,求解t数组的边界要注意一下。另外,t数组再求解前就全部初始化成当前节点权值就行了。

最终答案很显然:max(ans[1][k][0],ans[1][k][1])。

曾经错误:

naive的转移方程:

t[i][j][0]=max(t[i-1][j][0],t[i-1][j-p][0],t[i-1][j-p][1]+ans[son][p][0])
t[i][j][1]=max(t[i-1][j][1],t[i-1][j-p][1]+ans[son][p][1])

事实上,这道题转移t[i][j][0]的第3种(标红的)情况很容易遗漏。另外,很容易忽略走去与走回子节点花费的1或2步。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Edge
{
int to,next;
}edge[];
int ne,ans[][][],f1[];
int a[];
int n,k;
bool vis[];
void dfs(int u)
{
int j,kk=f1[u],p,v;
vis[u]=true;
for(j=;j<=k;j++)
ans[u][j][]=ans[u][j][]=a[u];
while(kk!=)
{
v=edge[kk].to;
if(!vis[v])
{
dfs(v);
for(j=k;j>=;j--)
{
for(p=;p<=j;p++)
ans[u][j][]=max(ans[u][j][],max(ans[u][j-p][]+ans[v][p-][],ans[u][j-p][]+ans[v][p-][]));
for(p=;p<=j;p++)
ans[u][j][]=max(ans[u][j][],ans[u][j-p][]+ans[v][p-][]);
}
}
kk=edge[kk].next;
}
}
int main()
{
int i,ta,tb;
while(scanf("%d%d",&n,&k)==)
{
ne=;
memset(ans,,sizeof(ans));
memset(vis,,sizeof(vis));
memset(f1,,sizeof(f1));
for(i=;i<=n;i++)
scanf("%d",&a[i]);
for(i=;i<n;i++)
{
scanf("%d%d",&ta,&tb);
edge[++ne].to=tb;
edge[ne].next=f1[ta];
f1[ta]=ne;
edge[++ne].to=ta;
edge[ne].next=f1[tb];
f1[tb]=ne;
}
dfs();
printf("%d\n",max(ans[][k][],ans[][k][]));
}
return ;
}

Apple Tree POJ - 2486的更多相关文章

  1. E - Apple Tree POJ - 2486

    E - Apple Tree POJ - 2486 Wshxzt is a lovely girl. She likes apple very much. One day HX takes her t ...

  2. Apple Tree POJ - 2486 (树形dp)

    题目链接: D - 树形dp  POJ - 2486 题目大意:一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走V步,最多能遍历到的权值 学习网址:https://blog.c ...

  3. Apple Tree POJ - 3321 dfs序列构造树状数组(好题)

    There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. ...

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

  5. 【POJ 2486】 Apple Tree(树型dp)

    [POJ 2486] Apple Tree(树型dp) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8981   Acce ...

  6. POJ 2486 Apple Tree

    好抽象的树形DP......... Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6411 Accepte ...

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

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

  8. poj 2408 Apple Tree

    http://poj.org/problem?id=2486 典型的回溯题目:特别是状态方程用三维的来标记是否要走回路. 题意:一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走 ...

  9. POJ - 3321 Apple Tree (线段树 + 建树 + 思维转换)

    id=10486" target="_blank" style="color:blue; text-decoration:none">POJ - ...

随机推荐

  1. java.sql.SQLException: [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称而且未指定默认驱动程序解决方法

    开发程序须要登录功能 .就不想用大数据库.直接用java连接access.     在自己机器上一切正常,  url直连 和配置数据源都没有问题.  公布到windows server2008 上 , ...

  2. 【APUE】fork函数

    #include <unisth.h> pid_t fork(void) fork函数被调用一次,返回两次.子进程的返回值是0,父进程的返回值是子进程的进程id. fork函数调用一次却返 ...

  3. 【转】C++函数的重载、覆盖和隐藏区别

    网上看到的关于C++函数的重载.覆盖和隐藏区别的回答,如下(其内容来源于C++面试宝典中一道题目): a.成员函数被重载的特征:(1)相同的范围(在同一个类中):(2)函数名字相同:(3)参数不同:( ...

  4. ==和equals的差别

    == 和 Equals 的差别 1. == 是一个运算符. 2.Equals则是string对象的方法.能够.(点)出来. 我们比較无非就是这两种 1.基本数据类型比較 2.引用对象比較 1.基本数据 ...

  5. CSDN公开课:SCRUM敏捷开发(2015-8-19 免费)

    当前最火的敏捷可能就是SCRUM了.但敏捷无法落地.对人要求太高.老板对敏捷动机不良等问题怎样解决呢?我将在CSDN的公开课上为大家分享"SCRUM敏捷开发".各位朋友有杀错没放过 ...

  6. JavaScript学习14:表单处理

    什么是表单? 在HTML中,表单是由<form>元素来表示的.而在JavaScript中,表单相应的则是HTMLFormElement类型.HTMLFormElement继承了HTMLEl ...

  7. 2016/4/7 datatype:①json ②XML

    ①JSON 1,postjsonxml.php     json用循环方式处理传来的值  for(key in data) for(var i=0;i<data.length;i++){data ...

  8. 借助ltp语义分析提取特征,之后,文本生成

    """地点-哪里有做-业务-的(正规|靠谱)-公司?地点-做-业务-的(正规|靠谱)-公司(有哪些?|的联系方式是什么?|哪家口碑好值得信赖?)地点-做-业务-(怎么能省 ...

  9. Java 解析excel2003和2007区别和兼容性问题(POI操作)

    最近在使用POI对excel操作中发现一些问题,2003和2007的区别还是蛮大的: 2007相关的包: poi-3.9.jar poi-examples-3.8.jar poi-excelant-3 ...

  10. Latex 1: 解决latex中遇到一个常见错误:"Improper alphabetic constant."

    1.问题: 本人是在WIN7下用texlive 2016,编辑器用的是WinEdt 10.1 ,运行如下代码: \documentclass{ctexbook} \begin{document} \t ...