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

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;
}

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

时间: 2024-11-03 05:23:20

P1270 “访问”美术馆(树形dp)的相关文章

洛谷 P1270 “访问”美术馆(树形DP)

P1270 “访问”美术馆 题目描述 经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动.艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向一个展览室.Peer知道每个展室里藏画的数量,并且他精确测量了通过每条走廊的时间.由于经验老到,他拿下一幅画需要5秒的时间.你的任务是编一个程序,计算在警察赶来之前,他最多能偷到多少幅画. 输入输出格式 输入格式: 第1行是警察赶到的时间,以s为单位.第2行描述了艺术馆的结构,是一串非负整数,成对地出现:每一对的第一个

luogu1270 “访问”美术馆 树形dp

传送门 树形dp f[i][j] - 到i号点,已经j时间了的最大偷画数 #include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, a, b) for(int i = a; i <= b; ++i) const int N = 107; const int S = 607; int s, n, f[N][S]; void dfs(int u) { int time, paint;

luogu P1270 &quot;访问&quot;美术馆 树dp

传送门 比较奇怪的树形背包 首先需要处理读入的问题 这题史诗递归读入 然后递归读入就不用建图 这题特点是只有叶子有价值 所以背包就不太有用 坑点就是这个人进去还得出来... 而且不能把时间都用完(导致75) Time cost: 35min Code: 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<queue> 6

wikioi 1163 访问艺术馆 树形dp

递归建树,由题知该树是一棵二叉树,且除根节点外其他点的度为0或2. dp[i][j]表示来到第i个走廊(还未走过这条走廊)还剩下j时间,能拿到最大的画的数量. dp[i][j]=max(dp[i][j],dp[lson[i]][k]+dp[rson][last_time-k]) #include<cstdio> #include<algorithm> using namespace std; int dp[200][700]; int id=0,x,y,s; struct node

P1270 “访问”美术馆

一道树形dp啦~~~ 其实我是做过这道题的加强版后才做的这道题--不过先由浅入深,先发这个~ 首先,我定义 f [ u ] [ i ] 为在第 u 个点上,给它时间为 i 是能获取的最大价值. 有一个需要注意,如果说这是一个展厅,设给这个点的时间为 t ,那么实际能偷画的时间只有 t - 双倍边权. 这也导致了如果这个点是一个分支,那么我给两边的时间和(就是我给这个点的时间)必定要大于等于二倍边权. 这样就避免了在dfs里传入无关的冗杂的变量,使得状态统一比较容易维护. 接下来贴代码: #inc

[DP总结]树形DP

树形DP 树形DP,顾名思义,是在树上进行DP操作,因此往往需要使用DP实现,在转移时,通常先递归求出子树中的解,再在根节点进行计算转移. 树中只有两种关系,一种是父子关系,一种是平行关系. 下面是几道简单的树形DP.从中我们可以窥出树形DP的本质. [luogu] P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是

codevs1163访问艺术馆(树形dp)

1163 访问艺术馆 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 皮尔是一个出了名的盗画者,他经过数月的精心准备,打算到艺术馆盗画.艺术馆的结构,每条走廊要么分叉为二条走廊,要么通向一个展览室.皮尔知道每个展室里藏画的数量,并且他精确地测量了通过每条走廊的时间,由于经验老道,他拿下一副画需要5秒的时间.你的任务是设计一个程序,计算在警察赶来之前(警察到达时皮尔回到了入口也算),他最多能偷到多少幅画. 输入描述 Input

Hihocoder 1035 [树形dp]

/* 题意: 不要低头,不要放弃,不要气馁,不要慌张. PS:人生第一道自己独立做出来的树形dp... 给一棵树,标号1到n,每条边有两个权值,步行时间和驾车时间.车在1号点. 给m个必须访问的关键点,求从1号点出发,访问所有关键点一遍的最小时间. 注意车可以停在任意地方,但是只有1号点有一辆车,人最后也可以停留在任意点. 思路: 1.子树方向(注意dp1 dp2 dp4都是保证人一定要返回该点的最优解) dp1代表该点起始有车,并且从该点出发访问完该点子树上所有的关键点车和人都返回的该点的最优

BZOJ 2878: [Noi2012]迷失游乐园( 树形dp )

一棵树的话直接树形dp(求出往下走和往上走的期望长度). 假如是环套树, 环上的每棵树自己做一遍树形dp, 然后暴力枚举(环上的点<=20)环上每个点跑经过环上的路径就OK了. --------------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm&