其实这题是我从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 【魔兽地图】的更多相关文章

  1. JSOI 2008 魔兽地图

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

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

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

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

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

  4. BZOJ 1017 魔兽地图

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

  5. BZOJ [JSOI2008]魔兽地图DotR

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

  6. 【百度地图API】如何制作一张魔兽地图!!——CS地图也可以,哈哈哈

    原文:[百度地图API]如何制作一张魔兽地图!!--CS地图也可以,哈哈哈 摘要: 你玩魔兽不?你知道如何做一张魔兽地图不?! 快来看此文吧! ---------------------------- ...

  7. [BZOJ]1017 魔兽地图DotR(JSOI2008)

    BZOJ第一页做着做着就能碰到毒题,做到BZOJ1082小C就忍了,没想到下一题就是这种东西.这种题目不拖出来枭首示众怎么对得起小C流逝的青春啊. Description DotR (Defense ...

  8. [JSOI2008]魔兽地图(树形dp)

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

  9. 【BZOJ1017】[JSOI2008]魔兽地图(动态规划)

    [BZOJ1017][JSOI2008]魔兽地图(动态规划) 题面 BZOJ 洛谷 题解 状态设一下,\(f[i][j][k]\)表示第\(i\)个物品,有\(j\)个用于合成,总花费为\(k\)的最 ...

随机推荐

  1. Unity图文混排

    http://blog.csdn.net/akof1314/article/details/49028279 http://blog.csdn.net/akof1314/article/details ...

  2. java基础语法(二)

    一.运算符 算数运算符 算数运算符用在数学表达式中,它们的作用和在数学中的作用一样. 操作符 描述 例子 + 两数相加 1+1=2 - 两数相减 2-1=1 * 两数相乘 1*1=1 / 两数相除 1 ...

  3. 在一台电脑上,添加多个Git的ssh key

    Git的第一套公秘钥默认名为 id_rsa ,如果你想要生成另外一个公钥,比如 aysee ,你也可以使用任何你喜欢的名字. 步骤如下:(总共四大操作) 一.生成ssh key 1.生成一个新的自定义 ...

  4. 深入Spring Security-获取认证机制核心原理讲解

    文/朱季谦 本文基于Springboot+Vue+Spring Security框架而写的原创笔记,demo代码参考<Spring Boot+Spring Cloud+Vue+Element项目 ...

  5. 如何编写高质量的C#代码(一)

    从"整洁代码"谈起 一千个读者,就有一千个哈姆雷特,代码质量也同样如此. 想必每一个对于代码有追求的开发者,对于"高质量"这个词,或多或少都有自己的一丝理解.当 ...

  6. Spark应用开发-关联分析

    在机器学习中,常用的主题有分类,回归,聚类和关联分析.而关联分析,在实际中的应用场景,有部分是用于商品零售的分析.在Spark中有相应的案例 在关联分析中,有一些概念要熟悉. 频繁项集,关联规则,支持 ...

  7. SpringMVC-08-整合SSM之基本环境搭建

    8. 整合SSM 环境要求 IDEA MySQL 5.5 Tomcat 9 Maven 3.5.2 要求: 需要熟练掌握MySQL数据库,Spring,JavaWeb及Mybatis知识,简单的前端知 ...

  8. opencv-python函数

    opencv-python读取.展示和存储图像 1.imshow函数 imshow函数作用是在窗口中显示图像,窗口自动适合于图像大小,我们也可以通过imutils模块调整显示图像的窗口的大小.函数官方 ...

  9. 在一张id连续的表中找出缺失的id

    有这样一张表: create table tb_lostid( id number(6,0) primary key not null, name nvarchar2(20) not null ) 可 ...

  10. 2. 构建DNS集群

    DNS是什么 DNS(Domain Name System,域名系统),是互联网上存储域名和IP映射关系的一个分布式数据库,他负责把域名转换为IP地址,或IP转换为域名,工作于OSI应用层之上,DNS ...