JSOI 2008 【魔兽地图】
其实这题是我从noip前就开始做的。。。那个时候打的Pascal,一直TLE,转了C++之后我又写了一遍,A了。。。
辛酸史:

题目描述:
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(幽灵附体)作为回报的。
数据范围:物品数(n)<=51,金币数(m)<=2000,限购数量(limit)<=100。
思路分析:
可以说是一道树上背包DP吧。
观察题目,注意到:限购数量是题目的关键,对于一个物品,它合成几件,或是把几件用于父亲装备的合成,是题目恶心的地方,既然这样的话我们就把它设计到状态里面。然后再看看数据范围,限购小于等于100——很明显了,出题人就是想让我们把限购数量放进状态里面。再和普通的背包结合一下,得到状态,f[u][i][j]表示:对于以u为根的子树,在以u为根的子树上,我们投入i个金币,并且把j个物品u用于父亲装备的合成,以u为根的子树能产生的最大力量值。
然后我们还需要一个g数组来辅助f数组的转移。g[i][j]表示:对于u的前i个儿子装备,在以它们为根的子树中投入j个金币,能得到的最大力量值。
转移时我们需要枚举的很重要的一环就是:制作几个u装备,从而让整个转移能够顺利地进行下去,我们把它设为l。
得到g数组的转移:g[i][j]=max(g[i][j],g[i-1][j-k]+f[v][k][l*need]) 其中v为u的第i个儿子,而need则为制作一个装备u需要几个装备v,k为在以v为根的子树中花费k个金币。
通过g数组的转移,继而得到f数组的转移:f[u][i][j]=max(f[u][i][j],g[siz[u]][i]+w[u]*(l-j)) 其中siz[u]表示u有几个儿子。
最后求答案的时候我们又需要一个dp数组来求解。(嗯,没错,一道题目,三个背包dp,我也不得不佩服出题人了——你是真TM的毒瘤!)
最后这个就是最简单的背包dp了(如果这个都想不到的话,建议你前往xx省xx市实验学校,和某张姓老师学习一段时间)
状态dp[i][j],表示前i个“终极装备”(终极装备就是无法用于合成的装备),花费j个金币,能得到的最大力量值。转移的时候枚举一下在第i个装备上花费多少金币就可以了,具体不懂的话还是看代码吧,太简单了,也不想多讲了。
代码实现:
#include<bits/stdc++.h>
using namespace std;
const int inf=1000000000;
int f[55][2005][105],g[55][2005],dp[55][2005];
int a[55][55],need[55][55],limit[55],cost[55],w[55],siz[55];
bool root[55],son[55];
int n,m;
void dfs(int u){
if (!son[u]){
limit[u]=min(limit[u],m/cost[u]);
for (int i=0;i<=limit[u];i++)
for (int j=0;j<=i;j++)
f[u][i*cost[u]][j]=w[u]*(i-j);
return;
}
limit[u]=inf;
for (int i=1;i<=siz[u];i++){
dfs(a[u][i]);
cost[u]+=cost[a[u][i]]*need[u][i];
limit[u]=min(limit[u],limit[a[u][i]]/need[u][i]);
}
limit[u]=min(limit[u],m/cost[u]);
memset(g,-0x3f,sizeof(g));
g[0][0]=0;
for (int l=limit[u];l>=0;l--){ //这里倒着枚举l,是为了避免多次给g数组赋初值
for (int i=1;i<=siz[u];i++)
for (int j=0;j<=m;j++)
for (int k=0;k<=j;k++)
g[i][j]=max(g[i][j],g[i-1][j-k]+f[a[u][i]][k][l*need[u][i]]);
for (int i=0;i<=l;i++)
for (int j=0;j<=m;j++)
f[u][j][i]=max(f[u][j][i],g[siz[u]][j]+w[u]*(l-i));
}
}
int main(){
memset(f,-0x3f,sizeof(f));
scanf("%d%d",&n,&m);
int nn,ans=0;
for (int i=1;i<=n;i++){
scanf("%d",&w[i]);
char ch[3]; scanf("%s",&ch);
if (ch[0]=='A'){
scanf("%d",&nn);
for (int j=1;j<=nn;j++) scanf("%d%d",&a[i][j],&need[i][j]),root[a[i][j]]=true;
son[i]=true; siz[i]=nn;
} else scanf("%d%d",&cost[i],&limit[i]);
}
int now=0;
for (int i=1;i<=n;i++)
if (!root[i]){
dfs(i); now++;
for (int j=0;j<=m;j++)
for (int k=0;k<=j;k++)
dp[now][j]=max(dp[now][j],dp[now-1][j-k]+f[i][k][0]);
}
for (int i=0;i<=m;i++) ans=max(ans,dp[now][i]);
printf("%d\n",ans);
return 0;
}
JSOI 2008 【魔兽地图】的更多相关文章
- JSOI 2008 魔兽地图
题目描述 DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) ...
- 【BZOJ-1017】魔兽地图DotR 树形DP + 背包
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1566 Solved: 705[Submit][S ...
- 1017: [JSOI2008]魔兽地图DotR - BZOJ
Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...
- BZOJ 1017 魔兽地图
Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...
- BZOJ [JSOI2008]魔兽地图DotR
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1243 Solved: 532[Submit][S ...
- 【百度地图API】如何制作一张魔兽地图!!——CS地图也可以,哈哈哈
原文:[百度地图API]如何制作一张魔兽地图!!--CS地图也可以,哈哈哈 摘要: 你玩魔兽不?你知道如何做一张魔兽地图不?! 快来看此文吧! ---------------------------- ...
- [BZOJ]1017 魔兽地图DotR(JSOI2008)
BZOJ第一页做着做着就能碰到毒题,做到BZOJ1082小C就忍了,没想到下一题就是这种东西.这种题目不拖出来枭首示众怎么对得起小C流逝的青春啊. Description DotR (Defense ...
- [JSOI2008]魔兽地图(树形dp)
DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allst ...
- 【BZOJ1017】[JSOI2008]魔兽地图(动态规划)
[BZOJ1017][JSOI2008]魔兽地图(动态规划) 题面 BZOJ 洛谷 题解 状态设一下,\(f[i][j][k]\)表示第\(i\)个物品,有\(j\)个用于合成,总花费为\(k\)的最 ...
随机推荐
- 教会舍友玩 Git (再也不用担心他的学习)
舍友长大想当程序员,我和他爷爷奶奶都可高兴了,写他最喜欢的喜之郎牌Git文章,学完以后,再也不用担心舍友的学习了(狗头)哪里不会写哪里 ~~~ 一 先来聊一聊 太多东西属于,总在用,但是一直都没整理的 ...
- HTML5总结整理
(仅供大家学习分享交流) 一.简介 1.前端开发最核心技术 我们知道,用所谓的网页三剑客已经不能满足需求了,那前端开发究竟要学习什么技术呢?网页最 主要由3部分组成:结构.表现和行为.网页现在新的标准 ...
- ui自动化---WebDriverApi接口
一.webdriver client原理 当测试脚本启动Chrome的时候,selenium-webdriver 会首先在新线程中启动Chrome浏览器.启动后selenium-webdriver会将 ...
- (超详细)动手编写 — 栈、队列 ( Java实现 )
目录 前言 栈 概念 栈的设计 编码实现 小结 队列 概念 队列的设计 编码实现 双端队列 概念 设计 编码 循环队列 循环队列 循环双端队列 声明 前言 栈 概念 什么是栈? **栈 **:是一种特 ...
- 内置函数:循环调用函数map和filter
1.map:循环调用函数,前面一定一定要加list,要不然不会被调用 map的格式:list(map(函数名,循环体)) #这里的函数只能写函数名,不要加() list(map(os.mkdir,[' ...
- unittest上下关联关系的接口——继承测试用例类
如果有上下关联,可以用到一个类继承测试用例类(里面的测试用例函数名不要带test)的方法去调用用例, 注意:如果放到同一个类会出现用例重复执行的情况 ,如果测试用例的函数带了test,一旦被调用,会被 ...
- Istio中的流量配置
Istio中的流量配置 目录 Istio中的流量配置 Istio注入的容器 Istio-init istio-proxy Envoy架构 Pilot-agent生成的初始配置文件 Envoy管理接口获 ...
- .NET 5 中 Target Framework 详解
作者:.NET Team 翻译:精致码农-王亮 原文:http://dwz.win/Q4v 我们希望极大地简化开发人员必须在项目文件和 NuGet 包中使用的TFM (Target Framework ...
- .NET Core加解密实战系列之——使用BouncyCastle制作p12(.pfx)数字证书
简介 加解密现状,编写此系列文章的背景: 需要考虑系统环境兼容性问题(Linux.Windows) 语言互通问题(如C#.Java等)(加解密本质上没有语言之分,所以原则上不存在互通性问题) 网上资料 ...
- 搜索引擎学习(一)初识Lucene
一.Lucene相关基础概念 定义:一个简易的工具包,实现文件搜索的功能,支持中文,关键字,多条件查询,凡是文件名或文件内容包含的都查出来. 数据分类:结构化数据(固定格式或有限长度的数据)和非结构化 ...