把这两个题放在一起,是因为这两个题差不多,难度递进其实是懒得写两个博客所以一起分享一下

访问“美术馆”

题目描述
经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动。艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向一个展览室。Peer知道每个展室里藏画的数量,并且他精确测量了通过每条走廊的时间。由于经验老到,他拿下一幅画需要5秒的时间。你的任务是编一个程序,计算在警察赶来之前,他最多能偷到多少幅画。

输入输出格式
输入格式:
第1行是警察赶到的时间,以s为单位。第2行描述了艺术馆的结构,是一串非负整数,成对地出现:每一对的第一个数是走过一条走廊的时间,第2个数是它末端的藏画数量;如果第2个数是0,那么说明这条走廊分叉为两条另外的走廊。数据按照深度优先的次序给出,请看样例。
一个展室最多有20幅画。通过每个走廊的时间不超过20s。艺术馆最多有100个展室。警察赶到的时间在10min以内。
输出格式:
输出偷到的画的数量
输入输出样例
输入样例#1:
60
7 0 8 0 3 1 14 2 10 0 12 4 6 2
输出样例#1:
2

思路

把时间乘以二作为边权,画的个数作为叶节点的权值,建一棵树。丑陋的图:(边权要乘以二)

设f[i][j]表示第j时刻i节点,所得最多画的个数,w为点权,ff为边权,u为父亲,v为儿子,则f[u][j] = max{f[u][j - k - ff] + f[v][k]},其实就是01背包。注意如果回来时时间一定要小于规定时间,所以我把时间减了1
常数巨大的丑陋代码

# include <stdio.h>
# include <stdlib.h>
# include <iostream>
# include <string.h>
# include <math.h>
using namespace std; # define IL inline
# define RG register
# define UN unsigned
# define ll long long
# define rep(i, a, b) for(RG int i = a; i <= b; i++)
# define per(i, a, b) for(RG int i = b; i >= a; i--)
# define uev(e, u) for(RG int e = ft[u]; e != -1; e = edge[e].nt)
# define mem(a, b) memset(a, b, sizeof(a))
# define max(a, b) ((a) > (b)) ? (a) : (b)
# define min(a, b) ((a) < (b)) ? (a) : (b) IL int Get(){
RG char c = '!'; RG int num = 0, z = 1;
while(c != '-' && (c > '9' || c < '0')) c = getchar();
if(c == '-') z = -1, c = getchar();
while(c >= '0' && c <= '9') num = num * 10 + c - '0', c = getchar();
return num * z;
} const int MAXN = 602;
struct Edge{
int to, nt, f;
} edge[MAXN << 1];
int m, cnt, w[MAXN], f[MAXN][MAXN], ft[MAXN], ans, t[MAXN], num[MAXN], s = 1, tot, k; IL void Add(RG int u, RG int v, RG int f){
edge[cnt] = (Edge){v, ft[u], f}; ft[u] = cnt++;
} IL void Dfs(RG int u){
per(j, 5, m) rep(i, 1, w[u]) if(j >= i * 5) f[u][j] = max(f[u][j], f[u][j - i * 5] + i);
uev(e, u){
RG int v = edge[e].to, ff = edge[e].f;
Dfs(v);
per(j, 1, m) rep(i, 1, m) if(j >= i + ff) f[u][j] = max(f[u][j], f[u][j - i - ff] + f[v][i]);
}
} IL void Build(RG int fa){
k++;
if(k > s) return;
w[++tot] = num[k];
Add(fa, tot, t[k] * 2);
if(num[k]) return;
RG int v = tot;
Build(v); Build(v);
} int main(){
mem(ft, -1);
m = Get() - 1;
while(scanf("%d%d", &t[s], &num[s]) != EOF) s++;
s--; w[++tot] = 0;
Build(1);
Dfs(1);
rep(i, 0, m) ans = max(ans, f[1][i]);
printf("%d\n", ans);
return 0;
}

接下来题目升级了。。。

偷天换日

题目背景
神偷对艺术馆内的名画垂涎欲滴准备大捞一把。
题目描述
艺术馆由若干个展览厅和若干条走廊组成。每一条走廊的尽头不是通向一个展览厅,就
是分为两个走廊。每个展览厅内都有若干幅画,每副画都有一个价值。经过走廊和偷画都是
要耗费时间的。
警察会在n 秒后到达进口,在不被逮捕的情况下你最多能得到的价值。

输入输出格式
输入格式:
第一行一个整数 n(n≤600)。
第二行若干组整数,对于每组整数(t,x),t 表示进入这个展览厅或经过走廊要耗费 t
秒的时间,若x>0 表示走廊通向的展览厅内有x 幅画,接下来
x对整数(w,c)表示偷一幅价值为 w 的画需要 c秒的时间。若
x=0 表示走廊一分为二。(t,c≤5; x≤30)
输入是按深度优先给出的。房间和走廊数不超过 300 个。
输出格式:
仅一个整数,表示能获得的最大价值。
输入输出样例
输入样例#1:
50
5 0 10 1 10 1 5 0 10 2 500 1 1000 2 18 1 1000000 4
输出样例#1:
1500

思路

基本和上面一样,用c存储偷每幅画的时间,vi存储每幅画的价值,w改为存储画在数组中的下标,把

    per(j, 5, m) rep(i, 1, w[u]) if(j >= i * 5) f[u][j] = max(f[u][j], f[u][j - i * 5] + i);

改为

if(w[u]){
RG int kk = w[u];
rep(i, 1, num[kk]) per(j, c[kk][i], m) f[u][j] = max(f[u][j], f[u][j - c[kk][i]] + vi[kk][i]); }

即可。。。可以参考下面的代码理解。
代码也差不多,都很丑

# include <stdio.h>
# include <stdlib.h>
# include <iostream>
# include <string.h>
# include <math.h>
using namespace std; # define IL inline
# define RG register
# define UN unsigned
# define ll long long
# define rep(i, a, b) for(RG int i = a; i <= b; i++)
# define per(i, a, b) for(RG int i = b; i >= a; i--)
# define uev(e, u) for(RG int e = ft[u]; e != -1; e = edge[e].nt)
# define mem(a, b) memset(a, b, sizeof(a))
# define max(a, b) ((a) > (b)) ? (a) : (b)
# define min(a, b) ((a) < (b)) ? (a) : (b) IL int Get(){
RG char c = '!'; RG int num = 0, z = 1;
while(c != '-' && (c > '9' || c < '0')) c = getchar();
if(c == '-') z = -1, c = getchar();
while(c >= '0' && c <= '9') num = num * 10 + c - '0', c = getchar();
return num * z;
} const int MAXN = 602;
struct Edge{
int to, nt, f;
} edge[MAXN << 1];
int m, cnt, w[MAXN], f[MAXN][MAXN], ft[MAXN], ans, t[MAXN], num[MAXN], s = 1, tot = 1, k, vi[MAXN][MAXN], c[MAXN][MAXN]; IL void Add(RG int u, RG int v, RG int f){
edge[cnt] = (Edge){v, ft[u], f}; ft[u] = cnt++;
} IL void Dfs(RG int u){
if(w[u]){
RG int kk = w[u];
rep(i, 1, num[kk]) per(j, c[kk][i], m) f[u][j] = max(f[u][j], f[u][j - c[kk][i]] + vi[kk][i]); }
uev(e, u){
RG int v = edge[e].to, ff = edge[e].f;
Dfs(v);
per(j, 1, m) rep(i, 1, m) if(j >= i + ff) f[u][j] = max(f[u][j], f[u][j - i - ff] + f[v][i]);
}
} IL void Build(RG int fa){
k++;
if(k > s) return;
w[++tot] = k;
Add(fa, tot, t[k] * 2);
if(num[k]) return;
RG int v = tot;
Build(v); Build(v);
} int main(){
return 0;
}

luogu 访问”美术馆“ && 偷天换日的更多相关文章

  1. 洛谷 偷天换日&&“访问”美术馆

    典型的树形DP 按理说是先做“访问美术馆”再做偷天换日. 但是我先做了偷天换日然后再做的“访问”美术馆 DP方程好推,偷天换日在遇到有展品的时候做背包,因为是先做的偷天换日,所以把偷天换日的输入w,c ...

  2. 洛谷 P1270 “访问”美术馆 解题报告

    P1270 "访问"美术馆 题目描述 经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动.艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向 ...

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

    P1270 “访问”美术馆 艺术馆最多有100个展室 ------> 节点数$<=100*2<2^{8}=256$ 所以可以开一个$f[i][j]$表示到第$i$个点为止花去$j$分 ...

  4. 洛谷 P1270 “访问”美术馆

    P1270 “访问”美术馆 题目描述 经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动.艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向一个展览室.Peer ...

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

    P1270 “访问”美术馆 题目描述 经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动.艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向一个展览室.Peer ...

  6. P1270 “访问”美术馆——不太一样的树形DP

    P1270 “访问”美术馆 dfs读入,存图有点像线段树: 在枚举时间时,要减去走这条边的代价: #include<cstdio> #include<cstring> #inc ...

  7. [luogu 1270] “访问”美术馆 (树形dp)

    传送门 Description 经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动.艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向一个展览室.Peer知道每 ...

  8. P1270 【“访问”美术馆】

    $\large{\text{一千个Oier程序中有一千种树形DP}}$ 思路都差不多的,但是每个人都有自己的状态定义与转移 不妨定义$dp[i][j]$表示,在$i$子树内,偷$j$张画,且不考虑根到 ...

  9. P1270 “访问”美术馆

    题目描述 经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动.艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向一个展览室.Peer知道每个展室里藏画的数量,并 ...

随机推荐

  1. htmlUtil 网页爬取工具

    Htmlunit是一款模拟浏览抓取页面内容的Java框架,具有js解析引擎(rhino),可以解析页面的js脚本,得到完整的页面内容,特殊适合于这种非完整页面的站点抓取 /** * 获取页面的TITL ...

  2. IOS中DES与MD5加密方案

      0 2 项目中用的的加密算法,因为要和安卓版的适配,中间遇到许多麻烦. MD5算法和DES算法是常见的两种加密算法. MD5:MD5是一种不可逆的加密算法,按我的理解,所谓不可逆,就是不能解密,那 ...

  3. python学习:猜数字游戏

    猜数字游戏   系统生成一个100以内的随机整数, 玩家有6次机会进行猜猜看,每次猜测都有反馈(猜大了,猜小了,猜对了-结束) 6次中,猜对了,玩家赢了. 否则系统赢了   #!/usr/bin/en ...

  4. Ubuntu 配置FTP服务器

    第三方的文件传输软件用着很不爽,想着自己搭建一个FTP来干活. 首先检查是否已经安装了FTP,输入命令: vsftpd -v  可以查看版本,如果没有安装,无法执行. 安装FTP p.p1 { mar ...

  5. Treap-平衡树学习笔记

    平衡树-Treap学习笔记 最近刚学了Treap 发现这种数据结构真的是--妙啊妙啊~~ 咳咳.... 所以发一发博客,也是为了加深蒟蒻自己的理解 顺便帮助一下各位小伙伴们 切入正题 Treap的结构 ...

  6. ajax请求中contentType与dataType区别

    contentType: 告诉服务器,我要发什么类型的数据,默认值: "application/x-www-form-urlencoded". dataType:告诉服务器,我要想 ...

  7. 奥酷流媒体服务系统AMS5.0

      2016年6月29日,北极星通对外发布AMS5.0版本,AMS是北极星通公司独立研发的高性能流媒体服务系统软件,可广泛应用于视频直播,视频点播,视频转码,视频录播等场合. AMS5.0增加功能: ...

  8. wired-wireless_priority

    有线网卡和无线网卡同时上网,优先级切换的设置方法 默认有线网卡优先权高 Q:如果你想改为无线高,How do? A: ①进入网络属性的有线网卡的连接属性,选择TCP/IP属性,点"高级... ...

  9. Hive 时间日期处理总结

    最近用hive比较多,虽然效率低,但是由于都是T+1的业务模式.所以也就不要求太多了,够用就行.其中用的吧比较多就是时间了,由于大数据中很多字段都不是标准的时间类型字段,所以期间涉及了很多的时间日期字 ...

  10. git命令 高级

    Git 分支 - 分支的删除 git删除本地分支 git branch -D br git删除远程分支 git push origin :br  (origin 后面有空格) clone服务器上的资源 ...