P1270 “访问”美术馆

  一道树形dp啦~~~

  其实我是做过这道题的加强版后才做的这道题……不过先由浅入深,先发这个~

  首先,我定义 f [ u ] [ i ] 为在第 u 个点上,给它时间为 i 是能获取的最大价值。

  有一个需要注意,如果说这是一个展厅,设给这个点的时间为 t ,那么实际能偷画的时间只有 t - 双倍边权。

  这也导致了如果这个点是一个分支,那么我给两边的时间和(就是我给这个点的时间)必定要大于等于二倍边权。

  这样就避免了在dfs里传入无关的冗杂的变量,使得状态统一比较容易维护。

  接下来贴代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
#define maxn 2000
int f[2000][2000],n,am=1;
void dfs(int x)
{
    int t,num;
    scanf("%d%d",&t,&num);
    t*=2;
    if(num)
    {
        for(int i=5+t;i<=100+t;i++)
        f[x][i]=min((i-t)/5,num);
        return ;
    }
    int l=++am;
    dfs(l);
    int r=++am;
    dfs(r);
    for(int i=t;i<=n;i++)
    for(int j=0;j<=i-t;j++)
    f[x][i]=max(f[x][i],f[l][j]+f[r][i-t-j]);
}
int main()
{
    scanf("%d",&n);
    n--;
    dfs(1);
    printf("%d",f[1][n]);
    return 0;
}

原文地址:https://www.cnblogs.com/popo-black-cat/p/10325018.html

时间: 2024-08-25 09:11:18

P1270 “访问”美术馆的相关文章

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

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

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

P1270 “访问”美术馆 艺术馆最多有100个展室 ------> 节点数$<=100*2<2^{8}=256$ 所以可以开一个$f[i][j]$表示到第$i$个点为止花去$j$分钟的最大价值 对于分叉的点,我们可以直走右边或直走左边,也可以两边都走一次,分别转移即可. 对于展室(叶节点),处理一下几分钟能拿几幅画. 因为要折返所以边权$*2$,并且总时间花费要严格小于deadline,所以总时间-1 #include<iostream> #include<cstdi

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

“访问”美术馆

传送门 这是一道神奇的树形DP,对它还是不需要建树,而且完全可以一边读入,一边DP出结果-- 首先我们看题目描述很显然是一棵二叉树,而且还是完全二叉树.(没啥卵用) 令dp[i][j]表示在第i个节点选取花费j时间所能获取的最大画数. 之后因为题目的输入是递归给出的--所以我们直接去建图难度很大,不妨直接边递归边求解.首先我们考虑,如果当前的节点是一个不会再分裂的点(他下面直接通向展览馆).我们直接更新这个节点的答案就可以. 之后如果他要能再分裂,先递归下去,之后在返回的途中,枚举对于左子树给其

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;

做题单

错误 收藏了过多题目 QWQ P1383 高级打字机 P1270 “访问”美术馆 P1481 魔族密码 P1280 尼克的任务 P1271 聚会的快乐 P3631 [APIO2011]方格染色 P1243 排序集合 P2858 [USACO06FEB]奶牛零食Treats for the Cows P3146 [USACO16OPEN]248 P2890 [USACO07OPEN]便宜的回文Cheapest Palindrome P1896 [SCOI2005]互不侵犯 P3154 [CQOI2

[DP总结]树形DP

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

初学树型dp

树型DP DFS的回溯是树形DP的重点以及核心,当回溯结束后,root的子树已经被遍历完并处理完了.这便是树形DP的最重要的特点 自己认为应该注意的点 好多人都说在更新当前节点时,它的儿子结点都给更新完了,实际上这并不准确.对于当前节点,我们需要dfs它的儿子,并且在dfs中进行dp.在此过程中并不是等到儿子都更新完我们才更新当前节点的信息(假设当前节点为x, 有儿子son1 , son2, son3, 且son1已经更新完了, 即x已有了son1的信息, son2刚刚更新完,即dfs正在son

Sqlserver通过链接服务器访问Oracle的解决办法

转自http://blog.sina.com.cn/s/blog_614b6f210100t80r.html 一.创建sqlserver链接服务(sqlserver链接oracle)  首先sqlserver 链接oracle可以通过两个访问接口: “MSDAORA” 和“OraOLEDB.Oracle” 1.“MSDAORA”访问接口是由Microsoft OLE DB Provider for Oracle提供的,这里建议不使用此接口进行链接.通过该访问接口建立的链接服务器在进行查询orac