博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
其他OJ 树型DP “访问”艺术馆
阅读量:6004 次
发布时间:2019-06-20

本文共 2127 字,大约阅读时间需要 7 分钟。

提交地址:http://www.cqoi.net:2012/JudgeOnline/problem.php?id=1286

这题是OI的经典题,不难,注意一点,原题是用文件输入输出的,但是这里的提交直接标准输入输出即可

这题的题意很清晰,明说了是二叉树(而且只能在两个孩子的节点和叶子节点)。

注意输入给出的信息,对于一对数据,a,b,a指通过走廊的时间,那是不是树中边的信息呢?不是的,应该是点的信息。树中每一个点都应该包含两个信息,就是时间花费和它有多少张画,对于非叶子节点而言,它的画数都是0,而时间是有的,对于叶子节点,除了有画数外,它也是有时间花费的

另外,本题读题要仔细,它是说在警察来之前就要离开,而不能在他来的时候离开,所以读入警察的到达时间后减1再开始计算

另外偷东西是要进去和出来的,所以如果经过了某个点往下走,就必定会经该店返回(树的性质可知),所以花费其实是两倍,所以我们在一开始保存点的花费的时候,就直接将时间花费保存为两倍,这样就相当于做到了返回

 

最后说一次DP思想

dp[rt][time]表示在rt这个点,剩下time时间能偷到最多的画

1.虽然时间有time,但要先花费掉通过该点的时间,tt=time-t[rt].cost

2.然后在tt时间内dp,dp[rt][time]= max{ dp[lch][i] + dp[rch][tt-i] }

这个方程很容易理解,一半时间去左边偷一半时间去右边偷,两者相加,再取最大值

3.而对于叶子节点,同样有时间花费的,所以同样先计算出tt,但是计算出tt后不用再递归了,而是计算在tt时间内最多可以拿多少画,并且这里肯定是尽量拿,只要时间还够的

但是注意一点,不能tt/5,因为时间够,但是可能画不够。。。我就是这样纠结了一下,才想起这个问题

至于怎么建树,输入已经是按照前序遍历序列给出的,那么就顺着输入,来个递归建树即可

 

#include 
#include
#include
using namespace std;#define N 550#define T 650#define max(a,b) ((a)>(b)?(a):(b))int n;struct node{ int lch,rch,cost,val;}t[N];pair
a[N];int dp[N][T];void build(int &m){ int rt=m; t[rt].cost=2*a[rt].first; t[rt].val=a[rt].second; if(a[m].second) { t[rt].lch=t[rt].rch=-1; return ; } t[rt].lch=m+1; build(++m); t[rt].rch=m+1; build(++m);}int dfs(int rt ,int time){ if(dp[rt][time]!=-1) return dp[rt][time]; if(time==0) return dp[rt][time]=0; if(t[rt].lch==-1) //叶子 { int c; if(t[rt].val*5 <= time-t[rt].cost) c=t[rt].val; else c=(time-t[rt].cost)/5; return dp[rt][time]=c; } dp[rt][time]=0; int tt=time-t[rt].cost; for(int i=0; i<=tt; i++) //枚举左孩子可以使用的时间 { int s1=dfs(t[rt].lch , i); int s2=dfs(t[rt].rch , tt-i); dp[rt][time]=max(dp[rt][time] , s1+s2); } return dp[rt][time];}int main(){ int time; scanf("%d",&time); time--; n=0; while(scanf("%d%d",&a[n].first,&a[n].second)!=EOF) n++; int m=0; build(m); memset(dp,-1,sizeof(dp)); dfs(0,time); printf("%d\n",dp[0][time]); return 0;}

 

转载于:https://www.cnblogs.com/scau20110726/archive/2013/04/07/3003504.html

你可能感兴趣的文章
JavaScript基础---函数
查看>>
前端每日实战:120# 视频演示如何用纯 CSS 创作锡纸撕开的文字效果
查看>>
Laravel实用小功能
查看>>
matplotlib绑定到PyQt5(有菜单)
查看>>
利用Powershell和ceye.io实现Windows账户密码回传
查看>>
Windows 8.1 今年 1 月市场份额超 Vista
查看>>
《设计团队协作权威指南》—第1章1.5节总结
查看>>
Chair:支付宝前端团队推出的Node.js Web框架
查看>>
《Total Commander:万能文件管理器》——第3.8节.后续更新
查看>>
BSD vi/vim 命令大全(下)[转]
查看>>
css3中变形与动画(一)
查看>>
[XMove-自主设计的体感解决方案] 系统综述
查看>>
【LINUX学习】磁盘分割之建立primary和logical 分区
查看>>
【YUM】第三方yum源rpmforge
查看>>
IOS(CGGeometry)几何类方法总结
查看>>
才知道系列之GroupOn
查看>>
⑲云上场景:超级减肥王,基于OSS的高效存储实践
查看>>
linux kswapd浅析
查看>>
变更 Linux、Ubuntu 时区、时间
查看>>
高仿QQ空间 侧滑Menu效果且换肤功能《IT蓝豹》
查看>>