题目大意:

他们需要购买装备来提升自己的力量值,每件装备都可以使佩戴它的英雄的力量值提高固定的点数,所以英雄的力量值等于它购买的所有装备的力量值之和。装备分为基本装备和高级装备两种。基本装备可以直接从商店里面用金币购买,而高级装备需要用基本装备或者较低级的高级装备来合成,合成不需要附加的金币。装备的合成路线可以用一棵树来表示。比如,Sange and Yasha的合成需要Sange,Yasha和Sange and Yasha Recipe Scroll三样物品。其中Sange又要用Ogre Axe, Belt of Giant Strength和 Sange Recipe Scroll合成。每件基本装备都有数量限制,这限制了你不能无限制地合成某些性价比很高的装备。现在,英雄Spectre有M个金币,他想用这些钱购买装备使自己的力量值尽量高。

已知每个高级装备需要哪些初级下一级装备以及需要几个

思路:

树形dp

dp i  j k表示第i种装备,有j个用于合成上一级装备,花k个金币

首先可以得到整个图应该是很多树

然后对于每个节点,我们都可以根据它的子树推出来

f[i][j][k]=max{c[i][k]+v[i]*(t-j)}

然后我们枚举这个节点有多少个需要用于合成(需要倒序枚举 不然爆炸)

最后对于每棵树

我们可以枚举钱数,来求出这棵树买多少

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<stack>
#define inf 2147483611
#define ll long long
#define MAXN 55
using namespace std;
inline 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,v[MAXN],cst[MAXN],lim[MAXN];
int cnt,to[MAXN*MAXN*],val[MAXN*MAXN*],first[MAXN],next[*MAXN*MAXN],ind[MAXN];//邻接表
int f[MAXN][MAXN*][MAXN*],c[MAXN][MAXN*],res[MAXN][MAXN*];
//f为dp数组 c记录某节点前x个子树花j个金币所获得最大收益 res记录前k棵树花j个金币获得最大收益
void add(int u,int v,int d) {next[++cnt]=first[u],first[u]=cnt,val[cnt]=d,to[cnt]=v,ind[v]++;}
void dp(int x)
{
if(!first[x])
{
lim[x]=min(lim[x],m/cst[x]);
for(int i=;i<=lim[x];i++)
for(int j=i;j<=lim[x];j++)
f[x][i][j*cst[x]]=v[x]*(j-i);
return ;
}
lim[x]=inf;
for(int i=first[x];i;i=next[i])
{
dp(to[i]);
lim[x]=min(lim[x],lim[to[i]]/val[i]);
cst[x]+=val[i]*cst[to[i]];
}
lim[x]=min(lim[x],m/cst[x]);
memset(c,-0x3f3f3f3f,sizeof(c));
c[][]=;
int cntt;
for(int t=lim[x];t>=;t--)
{
cntt=;
for(int i=first[x];i;i=next[i])
{
cntt++;
for(int j=;j<=m;j++)
for(int k=;k<=j;k++)
c[cntt][j]=max(c[cntt][j],c[cntt-][j-k]+f[to[i]][t*val[i]][k]);
}
for(int i=;i<=t;i++)
for(int j=;j<=m;j++)
f[x][i][j]=max(f[x][i][j],c[cntt][j]+(t-i)*v[x]);
}
}
int main()
{
memset(f,-0x3f3f3f3f,sizeof(f));
n=read(),m=read();
char ch[];int x,b,a,ans=;
for(int i=;i<=n;i++)
{
v[i]=read();
scanf("%s",ch);
if(ch[]=='A')
{
x=read();
for(int j=;j<=x;j++) {a=read(),b=read();add(i,a,b);}
}
else cst[i]=read(),lim[i]=read();
}
cnt=;
for(int g=;g<=n;g++)
{
if(!ind[g])
{
dp(g);
cnt++;
for(int i=;i<=m;i++)
for(int j=;j<=i;j++)
for(int k=;k<=lim[g];k++)
res[cnt][i]=max(res[cnt][i],res[cnt-][j]+f[g][k][i-j]);
}
}
for(int i=;i<=m;i++) ans=max(ans,res[cnt][i]);
printf("%d",ans);
}

orz vfk大佬速度惊人,博客太长了懒得看

bzoj 1017 魔兽地图DotR的更多相关文章

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

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

  2. BZOJ 1017 魔兽地图DotR(树形DP)

    题意:有两类装备,高级装备A和基础装备B.现在有m的钱.每种B有一个单价和可以购买的数量上限.每个Ai可以由Ci种其他物品合成,给出Ci种其他物品每种需要的数量.每个装备有一个贡献值.求最大的贡献值. ...

  3. BZOJ [JSOI2008]魔兽地图DotR

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

  4. BZOJ 1017 魔兽地图

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

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

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

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

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

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

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

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

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

  9. 【BZOJ】【1017】【JSOI2008】魔兽地图Dotr

    树形DP 一开始想:f[i][j]表示以 i 为根的子树,花 j 块钱能得到的最高力量值,结果发现转移的时候没法保证叶子结点的数量限制TAT 只好去膜拜题解了……在这里贴两篇泛型背包的文章吧:< ...

随机推荐

  1. Python模块 shelve xml configparser hashlib

    常用模块1. shelve 一个字典对象模块 自动序列化2.xml 是一个文件格式 写配置文件或数据交换 <a name="hades">123</a>3. ...

  2. java常见日期格式转换以及日期的获取

    package com.test.TestBoot.SingleModel;import java.text.SimpleDateFormat;import java.util.Date;public ...

  3. HTML5地理定位-Geolocation API

    HTML5提供了一组Geolocation API,来自navigator定位对象的子对象,获取用户的地理位置信息Geolocation API使用方法:1.判断是否支持 navigator.geol ...

  4. Java线程和多线程(一)——线程的基本概念

    Java 线程是一个轻量级执行任务的处理单元.Java提供了Thread类来支持多线程,开发者在应用中可以创建多个线程来支持并发执行任务. 在应用中存在两种类型的线程,用户线程和守护线程.当我们启动应 ...

  5. CSDN编写技巧--CSDN中高亮显示代码

    1, 最近在编写CSDN博客的时候,有种生不如死的感觉,就是如下的现象: 除了图中圈红圈的部分,还有就是背景色是灰色,并且,关键字不高亮显示,起始正常的情况下,也会有这块区域的最上边这行. 2, 有一 ...

  6. HDU 5492 Find a path

    Find a path Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID ...

  7. Windows Server 2012 防火墙如何添加端口例外的方法(转)

    Windows Server 2012 防火墙如何添加端口例外的方法 Windows Server 2012 防火墙如何添加端口例外的方法 在Windows Server 2012系统中,如果用户想在 ...

  8. 【转】Java IO流 overview

    Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  9. PHP上传文件限制修改

    php.ini里面查看如下行: upload_max_filesize post_max_size memory_limit

  10. csu1365 Play with Chain

    很显然的splay,第一次用splay操作区间...我实在佩服这个targan大佬,居然搞出这么牛逼的平衡树,调了大概5个小时终于搞定了.. #include<cstdio> #inclu ...