[JSOI2008]魔兽地图
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]魔兽地图的更多相关文章
- BZOJ [JSOI2008]魔兽地图DotR
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1243 Solved: 532[Submit][S ...
- 【BZOJ1017】[JSOI2008]魔兽地图(动态规划)
[BZOJ1017][JSOI2008]魔兽地图(动态规划) 题面 BZOJ 洛谷 题解 状态设一下,\(f[i][j][k]\)表示第\(i\)个物品,有\(j\)个用于合成,总花费为\(k\)的最 ...
- 【bzoj1017】[JSOI2008]魔兽地图DotR
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1658 Solved: 755[Submit][S ...
- [BZOJ1017][JSOI2008]魔兽地图DotR 树形dp
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 2597 Solved: 1010[Submit][ ...
- 1017: [JSOI2008]魔兽地图DotR - BZOJ
Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...
- [JSOI2008]魔兽地图(树形dp)
DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allst ...
- [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 ...
- [luogu4037 JSOI2008] 魔兽地图 (树形dp)
传送门 Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the ...
- BZOJ1017: [JSOI2008]魔兽地图DotR
传送门 设$f[i][j][k]$表示对于第$i$个点,向父节点贡献$j$个已合成的装备,花费了$k$的代价,最多获得的力量值. 单纯的$f[i][j][k]$是很难转移的,主要原因是无法维护和其他儿 ...
随机推荐
- 20155334 《网络攻防》 Exp9 Web安全基础
<网络攻防> Exp9 Web安全基础 一.实验后回答问题 SQL注入攻击原理,如何防御: 原理: 就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服 ...
- 不成功的RMAN恢复到其他机器的例子
事实上,RMAN备份的时候,如果是使用control file 来作catalog,那么一定要把control file和spfile恢复到另外的机器上面. 否则,会出现类似如下的错误: 原来的实例: ...
- STM32-M0中断优先级介绍
先解释中断优先级,后面讲代码的实现. 差异:M0的中断优先级相比于M4,没有用到分组,且只用到了2个bit位(即0~3)来设置,数值越小,优先级越高:同等优先级,根据终端号的大小来决定谁先执行. 根据 ...
- 让Visual Studio载入Symbol(pdb)文件
让Visual Studio载入Symbol(pdb)文件 让Visual Studio载入Symbol(pdb)文件 在VC编译工程的编译连接阶段,会产生Symbol文件,也就是常说的 pdb 文件 ...
- 【HNOI2016】矿区
题面 题解 知识引入 1. 平面图 一个图\(G=(V,E)\),若能将其画在平面上,且任意两条边的交点只能是\(G\)的顶点,则称\(G\)可嵌入平面,或称\(G\)是可平面的. 可平面图在平面上的 ...
- [BZOJ4851][JSOI2016]位运算[矩阵快速幂]
题意 给定长度为 \(\rm |S|\) 的 \(\rm 01\) 串并将其倍长 \(k\) 次得到一个 \(\rm|S|\times k\) 位的二进制数 \(R\) ,求有多少种在 \([0,R- ...
- AngularJS 的异步服务测试与Mocking
测试 AngularJS 的异步服务 最近,在做项目时掉进了 AngularJS 异步调用 $q 测试的坑中,直接躺枪了.折腾了许久日子,终于想通了其中的道道,但并不确定是最佳的解决方案,最后还是决定 ...
- python中字符串的常见操作方法
1. 字符串概念,字符串是一个容器,包含若干个字符并按照一定的顺序组织成一个整体.字符串支持索引操作. 2. 创建字符串基本语法 变量名 = "字符串信息" 变量名 = '字符串信 ...
- 转--看完让你彻底搞懂Websocket原理
偶然在知乎上看到一篇回帖,瞬间觉得之前看的那么多资料都不及这一篇回帖让我对 websocket 的认识深刻有木有.所以转到我博客里,分享一下.比较喜欢看这种博客,读起来很轻松,不枯燥,没有布道师的阵仗 ...
- 如何在百度云虚拟机中配置thinkphp5,并且url去掉index.php
第一步:将public目录下的index.php移到和public同级目录下,[或者直接在public同级目录下新建一个index.php] 第二步:那么这个新的index.php文件的内容如下: & ...