[BZOJ1017][JSOI2008]魔兽地图DotR 树形dp
1017: [JSOI2008]魔兽地图DotR
Time Limit: 30 Sec Memory Limit: 162 MB
Submit: 2597 Solved: 1010
[Submit][Status][Discuss]
Description
DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA
(Defense of the Ancients) Allstars。DotR里面的英雄只有一个属性——力量。他们需要购买装备来提升自己的
力量值,每件装备都可以使佩戴它的英雄的力量值提高固定的点数,所以英雄的力量值等于它购买的所有装备的力
量值之和。装备分为基本装备和高级装备两种。基本装备可以直接从商店里面用金币购买,而高级装备需要用基本
装备或者较低级的高级装备来合成,合成不需要附加的金币。装备的合成路线可以用一棵树来表示。比如,Sange
and Yasha的合成需要Sange,Yasha和Sange and Yasha Recipe Scroll三样物品。其中Sange又要用Ogre Axe, Belt
of Giant Strength和 Sange Recipe Scroll合成。每件基本装备都有数量限制,这限制了你不能无限制地合成某
些性价比很高的装备。现在,英雄Spectre有M个金币,他想用这些钱购买装备使自己的力量值尽量高。你能帮帮他
吗?他会教你魔法Haunt(幽灵附体)作为回报的。
Input
第一行包含两个整数,N (1 <= n <= 51) 和 m (0 <= m <= 2,000)。分别表示装备的种类数和金币数。装备
用1到N的整数编号。接下来的N行,按照装备1到装备n的顺序,每行描述一种装备。每一行的第一个非负整数表示这
个装备贡献的力量值。接下来的非空字符表示这种装备是基本装备还是高级装备,A表示高级装备,B表示基本装备
。如果是基本装备,紧接着的两个正整数分别表示它的单价(单位为金币)和数量限制(不超过100)。如果是高
级装备,后面紧跟着一个正整数C,表示这个高级装备需要C种低级装备。后面的2C个数,依次描述某个低级装备的
种类和需要的个数。
Output
第一行包含一个整数S,表示最多可以提升多少点力量值。
Sample Input
5 A 3 6 1 9 2 10 1
1 B 5 3
1 B 4 3
1 B 2 3
8 A 3 2 1 3 1 7 1
1 B 5 3
5 B 3 3
15 A 3 1 1 5 1 4 1
1 B 3 5
1 B 4 3
Sample Output
33
对于这道题,我们设f[i][j][k]表示处理到第i个点,向父亲节点合并j个装备,花了k元钱的最大力量值(不包括合并的j个)。
设g[i][j]表示当前节点的前i个子树花了j元钱的最大力量(不包括合并的)。
我们先枚举购买当前装备的总数量b,
对于f的转移,我们枚举j,k,有转移方程f[i][j][k]=max{g[i][k]+p[i]*(b-j)}
对于g的转移,我们枚举子树tot,钱数j和当前子树的钱数k,有g[tot][j]=max{g[tot-1][j-k]+f[i][b*e[i].v][k]}
之后统计答案即可
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int read() {
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,cnt,tot,ans;
int p[],L[],M[];
int f[][][];
int g[][],h[][];
char ch[];
int head[],deg[];
struct data{int to,next,v;}e[];
void add(int u,int v,int w){e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].v=w;cnt++;deg[v]++;}
void dfs(int now) {
if(head[now]<) {
L[now]=min(L[now],m/M[now]);
for(int i=;i<=L[now];i++)
for(int j=i;j<=L[now];j++) f[now][i][j*M[now]]=(j-i)*p[now];
return ;
}
L[now]=;
for(int i=head[now];i>=;i=e[i].next) {
int to=e[i].to;
dfs(to);
L[now]=min(L[now],L[to]/e[i].v);
M[now]+=e[i].v*M[to];
}
L[now]=min(L[now],m/M[now]);
memset(g,-,sizeof(g));
g[][]=;
for(int b=L[now];b>=;b--) {
int tot=;
for(int i=head[now];i>=;i=e[i].next) {
tot++;
for(int j=;j<=m;j++)
for(int k=;k<=j;k++){
g[tot][j]=max(g[tot][j],g[tot-][j-k]+f[e[i].to][b*e[i].v][k]);}
}
for(int i=;i<=b;i++)
for(int j=;j<=m;j++)
f[now][i][j]=max(f[now][i][j],g[tot][j]+p[now]*(b-i));
}
}
int main() {
memset(head,-,sizeof(head));
memset(f,-,sizeof(f));
n=read(),m=read();
for(int i=;i<=n;i++) {
p[i]=read();
scanf("%s",ch);
if(ch[]=='A') {
int x=read();
while(x--) {
int v=read(),num=read();
add(i,v,num);
}
}
else M[i]=read(),L[i]=read();
}
int sum=;
for(int x=;x<=n;x++) {
if(!deg[x]) {
dfs(x);
sum++;
for(int i=;i<=m;i++)
for(int j=;j<=i;j++)
for(int k=;k<=L[x];k++)
h[sum][i]=max(h[sum][i],h[sum-][j]+f[x][k][i-j]);
}
}
int ans=;
for(int i=;i<=m;i++) ans=max(ans,h[sum][i]);
cout<<ans;
}
[BZOJ1017][JSOI2008]魔兽地图DotR 树形dp的更多相关文章
- 【BZOJ-1017】魔兽地图DotR 树形DP + 背包
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1566 Solved: 705[Submit][S ...
- [bzoj1017][JSOI2008]魔兽地图 DotR (Tree DP)【有待优化】
Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...
- BZOJ1017: [JSOI2008]魔兽地图DotR【树形DP】【玄学】
Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...
- BZOJ1017 [JSOI2008]魔兽地图DotR 【树形dp + 背包dp】
题目链接 BZOJ1017 题解 orz hzwer 树形dp神题 设\(f[i][j][k]\)表示\(i\)号物品恰好花费\(k\)金币,并将\(j\)个物品贡献给父亲的合成时的最大收益 计算\( ...
- bzoj1017 [JSOI2008]魔兽地图DotR——DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1017 好难想的状态啊!f[i][j][k]表示i号物品有j个向上贡献,一共花了k钱的最大力量 ...
- BZOJ1017: [JSOI2008]魔兽地图DotR
传送门 设$f[i][j][k]$表示对于第$i$个点,向父节点贡献$j$个已合成的装备,花费了$k$的代价,最多获得的力量值. 单纯的$f[i][j][k]$是很难转移的,主要原因是无法维护和其他儿 ...
- 【bzoj1017】[JSOI2008]魔兽地图DotR
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1658 Solved: 755[Submit][S ...
- BZOJ [JSOI2008]魔兽地图DotR
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1243 Solved: 532[Submit][S ...
- 1017: [JSOI2008]魔兽地图DotR - BZOJ
Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...
随机推荐
- iOS Crash 分析 符号化崩溃日志
参考: http://blog.csdn.net/diyagoanyhacker/article/details/41247367 http://blog.csdn.net/diyagoanyhack ...
- HTML标准开头
<!doctype html> <html> <head> <meta charset="utf-8"> <title&g ...
- 利用插件对某些网页执行javascript代码
说明 javascript在浏览器地址栏中可以运行,也可以按F12在控制台中运行,还可以写一个插件让javascript针对某些网页执行,可以使用chrome浏览器的Content scripts,C ...
- 《Cracking the Coding Interview》——第16章:线程与锁——题目6
2014-04-27 20:25 题目:关于java中标有synchronized的成员方法? 解法:这代表同一个对象实例的synchronized方法不能被多个线程同时调用.注意有这么多个地方都加粗 ...
- 24、php知识点总结基础教程--part-2
1.表单处理 ①post请求 <html> <body> <form action="welcome.php" method="post&q ...
- soapUI的简单使用(webservice接口功能测试)
1.soapUI支持什么样的测试? 功能测试.性能测试.负载.回归测试等,它不仅仅可以测试基于 SOAP 的 Web 服务,也可以测试 REST 风格的 Web 服务. 1.SoapUI安装注意事项 ...
- Ubuntu15.04 python升级到python-3.6.x
简略记录步骤,容后补充: sudo add-apt-repository ppa:jonathonf/python-3.6 sudo apt-get update sudo apt-get i ...
- python-isinstance,issubclass
1 #当存在继承关系时,两个类中存在相同的方法,如何执行父类的方法,通过super 2 class C1: 3 def f1(self): 4 print('c1.f1') 5 6 7 class C ...
- 使用cloudbase-init初始化windows虚拟机
CloudBase-init简介 cloudbase-init 是 Windows 和其他系统的云初始化程序,可以设置主机名.创建用户.设置静态ip.设置密码等.对应的linux初始化程序是cloud ...
- 【志银】nginx_php_mysql_phpMyAdmin配置(Windows)
✄更新中... 更新日期:2018.11.22 ★版本说明+快捷下载(官网) nginx nginx-1.14.1 http://nginx.org/download/nginx-1.14.1. ...