bzoj 1017 : [JSOI2008]魔兽地图DotR

比较难想的的一道树形dp。

看到这道题正常的思路应该是$f[i][j][k]$表示i这棵子树里买了j个i物品花费为k的最大收益。

但如果直接这么定义的话转移复杂度会很高,需要枚举j,枚举孩子,枚举k,枚举孩子的花费,还要枚举每个孩子各买了多少件。

想办法把最后一个循环去掉。

重新定义状态$f[i][j][k]$表示表示i这棵子树里至少买了j个i物品花费为k的最大收益。

每次枚举完物品数量后加上这么一句

if(i!=l[x])f[x][i][j]=max(f[x][i][j],f[x][i+1][j]);

l[x]为x的最大数量。

相当于一个后缀最大值。

就可以轻松转移了。

虽然复杂度还是有些高。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #define inf 0x3f3f3f3f
 6 using namespace std;
 7 int n,m;
 8 int f[55][110][2005];
 9 int g[55][2005];
10 int v[55],cost[55],l[55];
11 int head[55],ver[110],nxt[110],tot,quan[110];
12 void add(int a,int b,int c)
13 {
14     tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;quan[tot]=c;return ;
15 }
16 bool vis[55];
17 void dfs(int x)
18 {
19     if(!head[x])
20     {
21         l[x]=min(l[x],m/cost[x]);
22         for(int i=0;i<=l[x];i++)
23         {
24             for(int j=0;j<=i;j++)
25             {
26                 f[x][j][i*cost[x]]=i*v[x];
27             }
28         }
29         return ;
30     }
31     l[x]=inf;
32     for(int i=head[x];i;i=nxt[i])
33     {
34         dfs(ver[i]);
35         l[x]=min(l[x],l[ver[i]]/quan[i]);
36         cost[x]+=cost[ver[i]]*quan[i];
37     }
38     l[x]=min(l[x],m/cost[x]);
39     memset(g,0xcf,sizeof(g));
40     g[0][0]=0;
41     for(int i=l[x];i>=0;i--)
42     {
43         int cnt=0;
44         for(int j=head[x];j;j=nxt[j])
45         {
46             cnt++;
47             for(int k=0;k<=m;k++)
48             {
49                 for(int l=0;l<=k;l++)
50                 {
51                     g[cnt][k]=max(g[cnt][k],g[cnt-1][l]+f[ver[j]][i*quan[j]][k-l]-v[ver[j]]*(i*quan[j]));
52                 }
53             }
54         }
55         for(int j=0;j<=m;j++)
56         {
57             f[x][i][j]=g[cnt][j]+i*v[x];
58             if(i!=l[x])f[x][i][j]=max(f[x][i][j],f[x][i+1][j]);
59         }
60     }
61
62     return ;
63 }
64 int main()
65 {
66     scanf("%d%d",&n,&m);
67     memset(f,0xcf,sizeof(f));
68     for(int i=1;i<=n;i++)
69     {
70         scanf("%d",&v[i]);
71         char s[2];scanf("%s",s);
72         if(s[0]==‘A‘)
73         {
74             int num;
75             int t1,t2;
76             scanf("%d",&num);
77             for(int j=1;j<=num;j++)
78             {
79                 scanf("%d%d",&t1,&t2);
80                 vis[t1]=1;
81                 add(i,t1,t2);
82             }
83         }
84         else
85         {
86             scanf("%d%d",&cost[i],&l[i]);
87         }
88     }
89     int root=0;
90     for(int i=1;i<=n;i++)
91     {
92         if(!vis[i])add(0,i,1);
93     }
94     dfs(root);
95     int ans=0;
96     for(int i=0;i<=m;i++)ans=max(ans,f[root][0][i]);
97     printf("%d\n",ans);
98     return 0;
99 }
时间: 2024-11-05 06:26:50

bzoj 1017 : [JSOI2008]魔兽地图DotR的相关文章

bzoj 1017[JSOI2008]魔兽地图DotR - 树形dp

1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec  Memory Limit: 162 MB Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars.DotR里面的英雄只有一个属性--力量.他们需要购买装备来提升自己的力量值,每件装备都可以使佩戴它的英雄的力量值提高固定的点数,所以英雄

[BZOJ 1017][JSOI2008]魔兽地图DotR(树形Dp)

Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars.DotR里面的英雄只有一个属性——力量.他们需要购买装备来提升自己的 力量值,每件装备都可以使佩戴它的英雄的力量值提高固定的点数,所以英雄的力量值等于它购买的所有装备的力 量值之和.装备分为基本装备和高级装备两种.基本装备可以直接从商店里面用金币购买,而高级装备需要用

【BZOJ 1017】 [JSOI2008]魔兽地图DotR

1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec  Memory Limit: 162 MB Submit: 1069  Solved: 433 [Submit][Status] Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars.DotR里面的英雄只有一个属性--力量.他们需要购

BZOJ [JSOI2008]魔兽地图DotR

1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1243  Solved: 532[Submit][Status][Discuss] Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars.DotR里面的英雄只有一个属性——力

BZOJ1017: [JSOI2008]魔兽地图DotR

传送门 设$f[i][j][k]$表示对于第$i$个点,向父节点贡献$j$个已合成的装备,花费了$k$的代价,最多获得的力量值. 单纯的$f[i][j][k]$是很难转移的,主要原因是无法维护和其他儿子的关系.所以对于每个节点再搞一个$g[i][j]$表示当前点的前$i$个儿子花费为$k$可以获得的最大的力量值. 然后肯定要先更新$g[][]$再以$g[][]$来更新$f[][][]$. 列出$g[i][j]$的状态转移方程就是: $g[cnt][k]=max \{ f[son][tol \ti

[JSOI2008][BZOJ1017] 魔兽地图DotR|树形动规

1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1254  Solved: 537[Submit][Status][Discuss] Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars.DotR里面的英雄只有一个属性——力

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

传送门 Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars. DotR里面的英雄只有一个属性--力量.他们需要购买装备来提升自己的力量值,每件装备都可以使佩戴它的英雄的力量值提高固定的点数,所以英雄的力量值等于它购买的所有装备的力量值之和.装备分为基本装备和高级装备两种.基本装备可以直接从商店里面用金币购买,而高级装备

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

DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Ancients) Allstars. DotR里面的英雄只有一个属性--力量.他们需要购买装备来提升自己的力量值,每件装备都可以使佩戴它的英雄的力量值提高固定的点数,所以英雄的力量值等于它购买的所有装备的力量值之和.装备分为基本装备和高级装备两种.基本装备可以直接从商店里面用金币购买,而高级装备需要用基本装备或者较低级的高级装

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

题意:有两类装备,高级装备A和基础装备B.现在有m的钱.每种B有一个单价和可以购买的数量上限.每个Ai可以由Ci种其他物品合成,给出Ci种其他物品每种需要的数量.每个装备有一个贡献值.求最大的贡献值.已知物品的合成路线是一个严格的树模型.即有一种物品不会合成其他任意物品,其余物品都会仅仅可用作合成另外一种物品 思路:f[i][j][k],代表第i个物品,花费了j,向上提供k个i物品. 1 #include<algorithm> 2 #include<cstdio> 3 #inclu