首页 > 其他 > 详细

P1270 “访问”美术馆(树形dp)

时间:2018-10-28 20:14:34      阅读:157      评论:0      收藏:0      [点我收藏+]

P1270 “访问”美术馆

艺术馆最多有100个展室 ------> 节点数$<=100*2<2^{8}=256$

所以可以开一个$f[i][j]$表示到第$i$个点为止花去$j$分钟的最大价值

对于分叉的点,我们可以直走右边或直走左边,也可以两边都走一次,分别转移即可。

对于展室(叶节点),处理一下几分钟能拿几幅画。

因为要折返所以边权$*2$,并且总时间花费要严格小于deadline,所以总时间-1

技术分享图片
#include<iostream>
#include<cstdio>
#include<cstring>
#define re register
using namespace std;
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a>b?a:b;}
int rt,u,s,f[302][602];
int dfs(int &o){
    int d,v,lc,rc; o=++u;
    scanf("%d%d",&d,&v);
    if(!v){
        int ld=dfs(lc),rd=dfs(rc);
        for(int i=s;i>=ld;--i)
            f[o][i]=max(f[o][i],f[lc][i-ld]);//只走左边
        for(int i=s;i>=rd;--i)
            f[o][i]=max(f[o][i],f[rc][i-rd]);//只走右边
        for(int i=ld;i<=s;++i)
            for(int j=rd;i+j<=s;++j)
                f[o][i+j]=max(f[o][i+j],f[lc][i-ld]+f[rc][j-rd]);//两边都走
    }else{
        for(int i=0;i<=s;++i) f[o][i]=min(i/5,v);//叶节点处理
    }return d<<1;//边权*2
}
int main(){
    scanf("%d",&s); --s;
    s-=dfs(rt); printf("%d",f[rt][s]);
    return 0;
}
View Code

 

P1270 “访问”美术馆(树形dp)

原文:https://www.cnblogs.com/kafuuchino/p/9866706.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!