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

10 59
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的更多相关文章

  1. 【BZOJ-1017】魔兽地图DotR 树形DP + 背包

    1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1566  Solved: 705[Submit][S ...

  2. [bzoj1017][JSOI2008]魔兽地图 DotR (Tree DP)【有待优化】

    Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...

  3. BZOJ1017: [JSOI2008]魔兽地图DotR【树形DP】【玄学】

    Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...

  4. BZOJ1017 [JSOI2008]魔兽地图DotR 【树形dp + 背包dp】

    题目链接 BZOJ1017 题解 orz hzwer 树形dp神题 设\(f[i][j][k]\)表示\(i\)号物品恰好花费\(k\)金币,并将\(j\)个物品贡献给父亲的合成时的最大收益 计算\( ...

  5. bzoj1017 [JSOI2008]魔兽地图DotR——DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1017 好难想的状态啊!f[i][j][k]表示i号物品有j个向上贡献,一共花了k钱的最大力量 ...

  6. BZOJ1017: [JSOI2008]魔兽地图DotR

    传送门 设$f[i][j][k]$表示对于第$i$个点,向父节点贡献$j$个已合成的装备,花费了$k$的代价,最多获得的力量值. 单纯的$f[i][j][k]$是很难转移的,主要原因是无法维护和其他儿 ...

  7. 【bzoj1017】[JSOI2008]魔兽地图DotR

    1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1658  Solved: 755[Submit][S ...

  8. BZOJ [JSOI2008]魔兽地图DotR

    1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1243  Solved: 532[Submit][S ...

  9. 1017: [JSOI2008]魔兽地图DotR - BZOJ

    Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...

随机推荐

  1. latex排版系统

    proTeXt - MiKTeX-based distribution for Windows proTeXt aims to be an easy-to-install TeX distributi ...

  2. hash算法和常见的hash函数 [转]

       Hash,就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值. 这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能 会散列成相同的输出,而不 ...

  3. CSS 一些基础知识(优先级、行内元素的一些属性、font-size单位) 怎样不加载图片

    CSS大小写不敏感 选择器优先级如下所示: 在属性后面使用 !important 会覆盖页面内任何位置定义的元素样式. 作为style属性写在元素内的样式 id选择器 类选择器 标签选择器 通配符选择 ...

  4. 什么是App加壳,以及App加壳的利与弊

    非著名程序员涩郎 非著名程序员,字耿左直右,号涩郎,爱搞机,爱编程,是爬行在移动互联网中的一名码匠!个人微信号:loonggg,微博:涩郎,专注于移动互联网的开发和研究,本号致力于分享IT技术和程序猿 ...

  5. Monkey、Monkeyrunner之间的区别

    Monkey.Monkeyrunner之间的区别 一.Monkey Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中.它向系统发送伪随机的用户事件流(如按键输入.触摸屏输 ...

  6. Sublime Text 2 中文乱码

    欲解决乱码问题,关键在于让Sublime Text 2支持GB2312和GBK.步骤如下:1.安装Sublime Package Control.在Sublime Text 2上用Ctrl+-打开控制 ...

  7. String类型的方法使用

    String.equals()方法源代码: public boolean equals(Object anObject) { if (this == anObject) { return true; ...

  8. SqlServer中截取小数位数

    方法一:convert(float,字段名) as 别名 select convert(float,round(10.123232,2)) 结果:10.12 select convert(float, ...

  9. NativeScript Vue 和 Weex 对比与分析

    Weex Weex是一个项目,由阿里巴巴创造.它的口号是“一次编写,到处运行”,这意味着你可以使用完全相同的代码库构建网站(HTML5),Android和iOS的应用.目前有几个Weex的生产项目,在 ...

  10. hdu 3986 Harry Potter and the Final Battle (最短路径)

    Harry Potter and the Final Battle Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/6553 ...