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

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int M=+;
  5. const int N=;
  6. const int inf=0x3f3f3f3f;
  7. int n,m;
  8. int L[N],P[N],C[N];
  9. int nd[N];
  10. bool ba[N];
  11. struct node{
  12. int nxt,to;
  13. }e[*N];
  14. int hd[N],cnt;
  15. void add(int x,int y){
  16. e[++cnt].nxt=hd[x];
  17. e[cnt].to=y;
  18. hd[x]=cnt;
  19. }
  20. void dp(int x){
  21. if(ba[x]){
  22. L[x]=min(L[x],m/C[x]);
  23. return;
  24. }
  25. for(int i=hd[x];i;i=e[i].nxt){
  26. int y=e[i].to;
  27. dp(y);
  28. C[x]+=C[y]*nd[y];
  29. L[x]=min(L[x],L[y]/nd[y]);
  30. }
  31. L[x]=min(L[x],m/C[x]);
  32.  
  33. }
  34. int f[N][][M];
  35. int g[N][M];
  36. int rt;
  37. bool du[N];
  38. void dfs(int x){
  39. if(ba[x]){
  40. for(int l=;l<=L[x];l++){
  41. for(int j=;j<=l;j++){
  42. f[x][j][l*C[x]]=P[x]*(l-j);
  43. }
  44. }
  45. return ;
  46. }
  47.  
  48. for(int i=hd[x];i;i=e[i].nxt){
  49. int y=e[i].to;
  50. dfs(y);
  51. }
  52.  
  53. for(int l=;l<=L[x];l++){
  54. int now=;
  55.  
  56. for(int i=hd[x];i;i=e[i].nxt){
  57. int y=e[i].to;
  58. now++;
  59. memset(g[now],-0x3f,sizeof g[now]);
  60. for(int j=;j<=m;j++){
  61. for(int k=;k<=j;k++){
  62. g[now][j]=max(g[now][j],g[now-][j-k]+f[y][l*nd[y]][k]);
  63. }
  64. }
  65.  
  66. }
  67. for(int h=;h<=l;h++){
  68. for(int k=;k<=m;k++){
  69. if(g[now][k]+(l-h)*P[x]>f[x][h][k]) {
  70. f[x][h][k]=g[now][k]+(l-h)*P[x];
  71.  
  72. }
  73.  
  74. }
  75. }
  76.  
  77. }
  78. }
  79. int main()
  80. {
  81. scanf("%d%d",&n,&m);
  82. char op;int s;
  83. memset(L,inf,sizeof L);
  84. for(int i=;i<=n;i++){
  85. scanf("%d ",&P[i]);
  86. op=getchar();
  87. if(op=='B'){
  88. ba[i]=;//is a leaf
  89. du[i]=;
  90. scanf("%d%d",&C[i],&L[i]);
  91. }
  92. else{
  93. scanf("%d",&s);
  94. int son;
  95. for(int j=;j<=s;j++){
  96. scanf("%d",&son);
  97. scanf("%d",&nd[son]);
  98. du[son]=;
  99. add(i,son);
  100. }
  101. }
  102. }
  103.  
  104. for(int i=;i<=n;i++) if(!du[i]) rt=i;
  105.  
  106. dp(rt);
  107.  
  108. memset(f,-inf,sizeof f);
  109. dfs(rt);
  110.  
  111. int ans=;
  112. for(int j=;j<=L[rt];j++){
  113. for(int k=;k<=m;k++){
  114. ans=max(ans,f[rt][j][k]);
  115. }
  116. }
  117. printf("%d",ans);
  118. return ;
  119. }

[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. js实现60秒倒计时效果(使用了jQuery)

    今天碰到要实现一个类似那种短信验证码60秒倒计时的需求,好久不写js,有点手生.把代码记录下,方便后续查阅. 这里我用了jQuey,毕竟写起来简洁点.下面直接看效果和代码. 一.效果          ...

  2. C++中的this和Python的self对比

    Python,当实例对象调用函数(函数其实都是属于类空间的)的时候,系统会自动将对象本身传入 函数在定义时的第一个变量一般是self.(但self并不是关键字,用其他名字也可以)         定义 ...

  3. Join 和 Apply 用法全解

    在关系型数据库系统中,为了满足第三范式(3NF),需要将满足“传递依赖”的表分离成单独的表,通过Join 子句将相关表进行连接,Join子句共有三种类型:外连接,内连接,交叉连接:外连接分为:left ...

  4. Flutter - 创建底部导航栏

    之前写过的一篇文章介绍了 Flutter - 创建横跨所有页面的侧滑菜单, 这次就一起来学习一下底部导航栏. 底部导航栏在ios平台上非常常见,app store就是这样的风格.还有就是大家最常用的微 ...

  5. Java容器类List、ArrayList、Vector及map、HashTable、HashMap的区别与用法

    Java容器类List.ArrayList.Vector及map.HashTable.HashMap的区别与用法 ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数 ...

  6. JMeter采用NON GUI模式时如何记录并查看错误

    在GUI模式下执行JMeter测试时,我们可以通过添加View Results Tree组件来查看JMeter请求的各类详情.那如果在正式测试场景中,当我们采用NON GUI模式时,遇到了断言或其他错 ...

  7. 【转载】kafka 基础知识

    1.       kafka介绍 1.1.       主要功能 根据官网的介绍,ApacheKafka®是一个分布式流媒体平台,它主要有3种功能: 1:It lets you publish and ...

  8. Beta博客集合

    Beta博客集合 Task1:beta冲刺准备 冲刺准备 Task2:Beta阶段冲刺合集 Beta阶段冲刺一 Beta阶段冲刺二 Beta阶段冲刺三 Beta阶段冲刺四 Beta阶段冲刺五 Task ...

  9. 在ubuntu下运行python脚本

    转自http://www.cnblogs.com/hester/p/5575658.html 1. 运行方式一 新建test.py文件: 1 touch test.py 然后vim test.py打开 ...

  10. Elasticsearch学习系列之term和match查询

    lasticsearch查询模式 一种是像传递URL参数一样去传递查询语句,被称为简单查询 GET /library/books/_search //查询index为library,type为book ...