Description

DotR里面的英雄只有一个属性——力量。

他们需要购买装备来提升自己的力量值,每件装备都可以使佩戴它的英雄的力量值提高固定的点数,所以英雄的力量值等于它购买的所有装备的力量值之和。

装备分为基本装备和高级装备两种。基本装备可以直接从商店里面用金币购买,而高级装备需要用基本
装备或者较低级的高级装备来合成,合成不需要附加的金币。装备的合成路线可以用一棵树来表示。

比如,Sange and Yasha的合成需要Sange,Yasha和Sange and Yasha Recipe Scroll三样物品。其中Sange又要用Ogre Axe, Belt
 of Giant Strength和 Sange Recipe Scroll合成。

每件基本装备都有数量限制,这限制了你不能无限制地合成某些性价比很高的装备。

现在,英雄Spectre有M个金币,他想用这些钱购买装备使自己的力量值尽量高。你能帮帮他吗?他会教你魔法Haunt(幽灵附体)作为回报的。

(1 <= n <= 51) 和 m (0 <= m <= 2,000)

Solution

一道搁置了很久的神题。

一看过去,一棵树形合成路线,子树的选择与能否合成根有关,而且要分配一个金币,最终获得最高收益。而且还有物品的限制。

所以,就是一道树形依赖背包题目了。

但是状态不是很好设,因为子树根的装备可能留下,也可能等着合成更高级的装备。

所以状态中必须要记录i根节点的子树,合成多少个i要用于上面的合成

设f[i][j][k]表示,以i为根的子树,合成j个i用于上面的合成,总共花费k元钱,也就是购买叶子花费k元。

转移的时候,

先把每个子树的答案算出来。

回溯到x后,外层枚举l表示合成几个x

然后依次选择每个子树,用树形背包。

注意,这里每个子树都要选择合成至少l*need[y]个,need[x]表示x合成一个父亲所需要的个数。

所以,不能像一般的背包,每个子树都要选择。

用分组背包,g[tot][j]表示,考虑了前tot个子树,花费j元钱,得到的最大力量。(每个子树都满足至少有l*need[y])个

g[tot][j]=max(g[tot-1][j-k]+f[y][l*nd[y]][k])

统计完了之后,

再枚举一个j,表示,l中留下j个合成x上一层的装备。

f[x][j][k]=max(g[tot][k]+(l-j)*P[x])

要注意的是,为了保证用了l*nd[y]个,必须令g,f初值是-inf

0肯定是不行的。那就可能会用少于l*nd[y]的钱就合成了l*nd个,虽然总力量是0,但是也可能是一个最优解。

有的时候,为了转移合法,必须把初值设置为极大或者极小值。

这样,每次的最优解,就必定会从这里出来。

可以顺便dp一下合成每个x所需要的价值,以及x合成的上限,可以减少循环的长度。

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=+;
const int N=;
const int inf=0x3f3f3f3f;
int n,m;
int L[N],P[N],C[N];
int nd[N];
bool ba[N];
struct node{
int nxt,to;
}e[*N];
int hd[N],cnt;
void add(int x,int y){
e[++cnt].nxt=hd[x];
e[cnt].to=y;
hd[x]=cnt;
}
void dp(int x){
if(ba[x]){
L[x]=min(L[x],m/C[x]);
return;
}
for(int i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
dp(y);
C[x]+=C[y]*nd[y];
L[x]=min(L[x],L[y]/nd[y]);
}
L[x]=min(L[x],m/C[x]); }
int f[N][][M];
int g[N][M];
int rt;
bool du[N];
void dfs(int x){
if(ba[x]){
for(int l=;l<=L[x];l++){
for(int j=;j<=l;j++){
f[x][j][l*C[x]]=P[x]*(l-j);
}
}
return ;
} for(int i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
dfs(y);
} for(int l=;l<=L[x];l++){
int now=; for(int i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
now++;
memset(g[now],-0x3f,sizeof g[now]);
for(int j=;j<=m;j++){
for(int k=;k<=j;k++){
g[now][j]=max(g[now][j],g[now-][j-k]+f[y][l*nd[y]][k]);
}
} }
for(int h=;h<=l;h++){
for(int k=;k<=m;k++){
if(g[now][k]+(l-h)*P[x]>f[x][h][k]) {
f[x][h][k]=g[now][k]+(l-h)*P[x]; } }
} }
}
int main()
{
scanf("%d%d",&n,&m);
char op;int s;
memset(L,inf,sizeof L);
for(int i=;i<=n;i++){
scanf("%d ",&P[i]);
op=getchar();
if(op=='B'){
ba[i]=;//is a leaf
du[i]=;
scanf("%d%d",&C[i],&L[i]);
}
else{
scanf("%d",&s);
int son;
for(int j=;j<=s;j++){
scanf("%d",&son);
scanf("%d",&nd[son]);
du[son]=;
add(i,son);
}
}
} for(int i=;i<=n;i++) if(!du[i]) rt=i; dp(rt); memset(f,-inf,sizeof f);
dfs(rt); int ans=;
for(int j=;j<=L[rt];j++){
for(int k=;k<=m;k++){
ans=max(ans,f[rt][j][k]);
}
}
printf("%d",ans);
return ;
}

[JSOI2008]魔兽地图的更多相关文章

  1. BZOJ [JSOI2008]魔兽地图DotR

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

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

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

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

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

  4. [BZOJ1017][JSOI2008]魔兽地图DotR 树形dp

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 20155218 Exp1 PC平台逆向破解(5)M

    20155218 Exp1 PC平台逆向破解(5)M 1. 掌握NOP.JNE.JE.JMP.CMP汇编指令的机器码 NOP:NOP指令即"空指令".执行到NOP指令时,CPU什么 ...

  2. adb连接手机的两种方式

    adb连接手机进行调试有两种方式,一种使用USB线,一种使用无线WiFi. 第一种  使用USB线连接 1. 在手机上启用USB调试 2. CMD窗口输入adb devices,此时可以看到自己的设备 ...

  3. 第一次软件工程作业(One who wants to wear the crown, Bears the crown.)

    回顾你过去将近3年的学习经历 1.当初报考的时候,是真正的喜欢计算机这个专业吗? 报考时对于计算机专业只能说不讨厌,也可以认为对其没有任何的感觉. 有一个比我自己还注意我未来的老妈,我的报考只能通过一 ...

  4. centos 7 git的管理和使用

    一.linux 安装git (服务端) 1.首先创建用户账号 useradd zlx passwd zlx .... 2.创建目录git仓库 mkdir zlx_git.git 3.赋权限 chown ...

  5. 《杜增强讲Unity之Tanks坦克大战》11-游戏流程控制

    11 游戏流程控制 使用协程来控制游戏流程 11.1 添加MessageText 首先添加一个Text来显示文字   image 设置GameMgr   image 11.2 游戏整体流程 下面Gam ...

  6. Istio如何使用相同的端口访问网格外服务

    1.1.背景 写这篇文章的目的是为了说明以下问题:如何使用TCP协议相同的端口访问网格外多个服务? 这是最近直播的时候有一个同学提出的,当时我没有完全明白,“访问多集群” 的意思.后来仔细思考了一下, ...

  7. 详细聊聊k8s deployment的滚动更新(一)

    一.知识准备 ● 本文详细探索deployment在滚动更新时候的行为 二.环境准备 组件 版本 OS Ubuntu 18.04.1 LTS docker 18.06.0-ce 三.准备镜像 首先准备 ...

  8. 5分钟让你明白HTTP协议

    一.HTTP简介 1.http协议介绍 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标 ...

  9. 《Linux内核设计与实现》 第三周 读书笔记

    第一章 Linux内核简介 1. Unix的历史 Unⅸ虽然已经使用了40年,但计算机科学家仍然认为它是现存操作系统中最强大和最优秀的系统. Unix强大的根本原因: 简洁 在Unix中所有的东西都被 ...

  10. Linux内核分析——第一周学习笔记

    20135313吴子怡.北京电子科技学院 chapter 1 知识点梳理 第一节 存储程序计算机工作模型 1.冯诺依曼体系结构:即具有存储程序的计算机体系结构.目前大多数拥有计算和存储功能的设备(智能 ...