POJ 2486
因为苹果可能在不同的子树中,所以,很容易想到设状态dp_back[i][j]为以i点为树根走j步并回到i点的最大苹果数与dp_to[i][j]不回到i点的两个状态。
于是,转移方程就很明显了。只是注意要减去一来一回,或者不回的边。树形DP里套背包。
但这题远比这复杂,个人认为。因为在实现上细节太多。
实现代码1:
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std; const int MAX=;
vector<int>G[MAX];
int num[MAX],dp_back[MAX][MAX*],dp_to[MAX][MAX*];
int tback[MAX*],tto[MAX*];
int n,s; void init(){
for(int i=;i<=n;i++)
G[i].clear();
memset(dp_back,,sizeof(dp_back));
memset(dp_to,,sizeof(dp_to));
} void dfs(int u,int f){
int size=G[u].size();
for(int i=;i<size;i++){
int v=G[u][i];
if(v!=f){
dfs(v,u);
for(int p=;p<=s;p++){
tback[p]=dp_back[u][p];
tto[p]=dp_to[u][p];
for(int k=;k<=p;k++){
if(p-k->=){
tback[p]=max(tback[p],dp_back[u][p-k-]+dp_back[v][k]+num[v]);
}
if(p-k->=){
tto[p]=max(tto[p],dp_back[u][p-k-]+dp_to[v][k]+num[v]);
}
if(p-k->=){
tto[p]=max(tto[p],dp_to[u][p-k-]+dp_back[v][k]+num[v]);
}
}
}
for(int j=;j<=s;j++){
dp_back[u][j]=tback[j];
dp_to[u][j]=tto[j];
}
}
}
} int main(){
int u,v;
while(scanf("%d%d",&n,&s)!=EOF){
init();
for(int i=;i<=n;i++)
scanf("%d",&num[i]);
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(,);
int ans=max(dp_to[][s],dp_back[][s]);
ans+=num[];
printf("%d\n",ans);
}
return ;
}
这是我WA了N久后看了别人的改过来的,每次在DP时才把根节点的值加上。说不清为什么,但是对了。
另一个是我原本WA的代码,可以把OJ的讨论板所有数据都过了,但依然WA,后来研究了好久,发现自己代码上的一个问题,那就是当最大步数超过边数的两倍时,就会出现问
题,于是,我只好投机一点,最后扫描一次结果值来获得正确值了。
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std; const int MAX=;
vector<int>G[MAX];
int num[MAX],dp_back[MAX][MAX*],dp_to[MAX][MAX*];
int tback[MAX*],tto[MAX*];
int n,s; void init(){
for(int i=;i<=n;i++)
G[i].clear();
memset(dp_back,,sizeof(dp_back));
memset(dp_to,,sizeof(dp_to));
} void dfs(int u,int f){
int size=G[u].size();
dp_back[u][]=num[u];
dp_to[u][]=num[u];
for(int i=;i<size;i++){
int v=G[u][i];
if(v!=f){
dfs(v,u);
for(int p=;p<=s;p++){
tback[p]=dp_back[u][p];
tto[p]=dp_to[u][p];
for(int k=;k<=p;k++){
if(p-k->=){
tback[p]=max(tback[p],dp_back[u][p-k-]+dp_back[v][k]);
}
if(p-k->=){
tto[p]=max(tto[p],dp_back[u][p-k-]+dp_to[v][k]);
}
if(p-k->=){
tto[p]=max(tto[p],dp_to[u][p-k-]+dp_back[v][k]);
}
}
}
for(int j=;j<=s;j++){
dp_back[u][j]=tback[j];
dp_to[u][j]=tto[j];
}
}
}
} int main(){
int u,v;
while(scanf("%d%d",&n,&s)!=EOF){
init();
for(int i=;i<=n;i++)
scanf("%d",&num[i]);
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(,);
// int ans=max(dp_to[1][s],dp_back[1][s]);
// ans+=num[1];
int ans=;
for(int i=;i<=s;i++)
ans=max(ans,max(dp_back[][i],dp_to[][i]));
printf("%d\n",ans);
}
return ;
}
两个代码除了初始化的位置不一样,其他都是一样的。但我感觉代码2更符合本来的转移方程,你看一下初始化的位置就明白。但最终问题时,不能处理好,那就是当最大步数超过边数的两倍时问题,因为我在初始化时就认为这是一种不可能的情况了。。。
所以,请路过大牛给指点,以去掉最后的扫描一次得到结果。。。
POJ 2486的更多相关文章
- 【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 ...
- Apple Tree POJ - 2486 (树形dp)
题目链接: D - 树形dp POJ - 2486 题目大意:一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走V步,最多能遍历到的权值 学习网址:https://blog.c ...
- Apple Tree POJ - 2486
Apple Tree POJ - 2486 题目大意:一棵点带权有根树,根节点为1.从根节点出发,走k步,求能收集的最大权值和. 树形dp.复杂度可能是O(玄学),不会超过$O(nk^2)$.(反正这 ...
- 【POJ 2486】 Apple Tree(树型dp)
[POJ 2486] Apple Tree(树型dp) Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8981 Acce ...
- 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 ...
- poj 2486( 树形dp)
题目链接:http://poj.org/problem?id=2486 思路:经典的树形dp,想了好久的状态转移.dp[i][j][0]表示从i出发走了j步最后没有回到i,dp[i][j][1]表示从 ...
- POJ 2486 Apple Tree(树形dp)
http://poj.org/problem?id=2486 题意: 有n个点,每个点有一个权值,从1出发,走k步,最多能获得多少权值.(每个点只能获得一次) 思路: 从1点开始,往下dfs,对于每个 ...
- POJ 2486 Apple Tree
好抽象的树形DP......... Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6411 Accepte ...
- poj 2486 Apple Tree(树形DP 状态方程有点难想)
Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9808 Accepted: 3260 Descri ...
- POJ 2486 Apple Tree(树形DP)
题目链接 树形DP很弱啊,开始看题,觉得貌似挺简单的,然后发现貌似还可以往回走...然后就不知道怎么做了... 看看了题解http://www.cnblogs.com/wuyiqi/archive/2 ...
随机推荐
- Java图形用户界面编程
1.Java图形用户界面编程概述 JavaAPI中提供了两套组件用于支持编写图形用户界面:AWT(抽象窗口包)和Swing 2. 容器(Container):重量级容器和轻量级容器(一个容器可以放置 ...
- 73. 解决ExtJS TreePanel 的 iconCls设置问题
转自:https://blog.csdn.net/hanchuang213/article/details/62881568 很久没有写代码了,最近在做一个在线帮助网站,于是又捡起了 ExtJS,我用 ...
- asp.net限制了上传文件大小为..M,解决方法
asp.net限制了上传文件大小为4M,在:在web.config里加下面一句,加在<System.web></System.web>之间如下:<system.web&g ...
- C#比较两个日期的大小 .net
using System;using System.Collections; public class MyClass{public static void Main(){DateTime dt1 = ...
- Jquery中绑定事件的异同
谈论jquery中bind(),live(),delegate(),on()绑定事件方式 1. Bind() $(selector).bind(event,data,function) Event:必 ...
- Java中的synchronized
学习 https://blog.csdn.net/a158123/article/details/78607964 以及 https://www.cnblogs.com/beiyetengqing/p ...
- SQLServer 里的三种条件判断的用法:Where GroupBy Having
HAVING 子句对 GROUP BY 子句设置条件的方式与 WHERE 子句和 SELECT 语句交互的方式类似.WHERE 子句搜索条件在进行分组操作之前应用:而 HAVING 搜索条件在进行分组 ...
- C# 跨平台换行符 System.Environment.NewLine
C# 跨平台换行符 System.Environment.NewLine
- 2星|《10W+走心文案是怎样炼成的》:标题党。实际是台湾创意总监的一些人生感悟和两三个很一般的创意文案
10W+走心文案是怎样炼成的 作者是台湾人,曾在台湾奥美担任创意总监,做过一些广告.本书是他的一些经验介绍. 总体来说是标题党,作者的广告基本是电视广告,跟文案也有关系,估计播放量也很容易过10W+, ...
- NET MVC FileResult 导出/下载 文件/Excel
参考http://www.cnblogs.com/ldp615/archive/2010/09/17/asp-net-mvc-file-result.html 1.引入NPOI 2.代码 using ...