题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1017

钱数很少,所以它也能压进状态里。

还有向上贡献几个物品。所以状态就是第 i 号物品,向上贡献 j 个,总共花 k 元的当前就能得到的力量。

然后可以树形dp。

不同的是平常的树形dp,该点的值就顺便充当前 r 个子树的值;遍历完子树就完成自己的值。

  但这里的状态里有一个“向上贡献 j 个”,不太好弄。所以另开一个 g ,只关注花了多少钱和带来多少力量。

  为了能用这个g转移到dp,不出现花了某些钱其实买不够向上贡献的 j 个当前物品的情况,应该把“总共买 l 个当前物品”放在最外面枚举。

    并且是倒序,为了沿用上一轮的g值。

**不知为何,自己的代码比别人慢了好多!!我觉得没什么不同呀……以后再来看看吧。

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=,M=;const ll INF=0x7fffffff;
int n,m,head[N],xnt,du[N];
ll a[N],L[N],c[N],dp[N][N<<][M],g[N][M],h[N][M],ans;//dp[][N<<1][]不能dp[][N][]
struct Edge{
int next,to;ll w;
Edge(int n=,int t=,ll w=):next(n),to(t),w(w) {}
}edge[N];
void dfs(int cr)
{
if(!head[cr])
{
L[cr]=min(L[cr],m/c[cr]);
for(int i=;i<=L[cr];i++)
for(int j=;j<=i;j++)
dp[cr][j][i*c[cr]]=(i-j)*a[cr];
return;
}
L[cr]=INF;
for(int i=head[cr],v;i;i=edge[i].next)
{
dfs(v=edge[i].to);L[cr]=min(L[cr],L[v]/edge[i].w);
c[cr]+=c[v]*edge[i].w; //只是用来限制L[cr]
}
L[cr]=min(L[cr],m/c[cr]);
memset(g,-,sizeof g);//g只和子树阶段、钱有关,因为dp涉及"向上贡献几个",所以不方便同时表示前几个子树的力量值
g[][]=;
for(int l=L[cr];l>=;l--)//g不重赋值,所代表的状态应该足以合成当前的l个当前装备;所以需倒序
{
int tot=;
for(int i=head[cr];i;i=edge[i].next)
{
tot++;
for(int k=;k<=m;k++)//用了k钱
for(int j=;j<=k;j++)//j钱给v
g[tot][k]=max(g[tot][k],g[tot-][k-j]+dp[edge[i].to][l*edge[i].w][j]);//k-j钱给之前的子树
}
for(int j=;j<=l;j++)
for(int k=;k<=m;k++)
dp[cr][j][k]=max(dp[cr][j][k],g[tot][k]+a[cr]*(l-j));//子树们的节余+自己的节余
}
}
int main()
{
scanf("%d%d",&n,&m);char ch;int u,x;ll z;
memset(L,,sizeof L);
memset(dp,-,sizeof dp);//////
for(int i=;i<=n;i++)
{
scanf("%lld %c",&a[i],&ch);
if(ch=='B')
{
scanf("%lld%lld",&c[i],&L[i]);
}
else
{
scanf("%d",&u);
for(int j=;j<=u;j++)
{
scanf("%d%lld",&x,&z);
edge[++xnt]=Edge(head[i],x,z);head[i]=xnt;du[x]++;
}
}
}
int tot=;
for(int i=;i<=n;i++)
if(!du[i])
{
dfs(i);tot++;
for(int k=;k<=m;k++)//总共
for(int j=;j<=m;j++)//给之前的树
h[tot][k]=max(h[tot][k],h[tot-][j]+dp[i][][k-j]);
}
for(int i=;i<=m;i++)ans=max(ans,h[tot][i]);
printf("%lld",ans);
return ;
}

bzoj1017(JSOI2008)魔兽地图的更多相关文章

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

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

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

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

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

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

  4. BZOJ1017 [JSOI2008]魔兽地图DotR 【树形dp + 背包dp】

    题目链接 BZOJ1017 题解 orz hzwer 树形dp神题 设\(f[i][j][k]\)表示\(i\)号物品恰好花费\(k\)金币,并将\(j\)个物品贡献给父亲的合成时的最大收益 计算\( ...

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

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

  6. bzoj1017 [JSOI2008]魔兽地图DotR——DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1017 好难想的状态啊!f[i][j][k]表示i号物品有j个向上贡献,一共花了k钱的最大力量 ...

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

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

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

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

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

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

随机推荐

  1. 搞懂分布式技术10:LVS实现负载均衡的原理与实践

    搞懂分布式技术10:LVS实现负载均衡的原理与实践 浅析负载均衡及LVS实现 原创: fireflyc 写程序的康德 2017-09-19 负载均衡 负载均衡(Load Balance,缩写LB)是一 ...

  2. Using Oracle Database In-Memory with Oracle E-Business Suite

    Database In-Memory is one of a number of options that can be deployed to address Oracle E-Business S ...

  3. Shell test 命令,Shell 输入/输出重定向

    一.Shell test 命令 Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值.字符和文件三个方面的测试. 数值测试 参数 说明 -eq 等于则为真 -ne 不等于则为真 -g ...

  4. Java进阶1. Synchronized 关键字

    Java进阶1. Synchronized 关键字 20131025 1.关于synchronized的简介: Synchronized 关键字代表对这个方法加锁,相当于不管那一个线程,运行到这个方法 ...

  5. 利用 LINQ的skip和Take 方法对List实现分页效果

    var testList=new List<string>(); )).Take(pageSize); //skip是跳过的条数,pageSize*(pageIndex-),Take 是返 ...

  6. APUE学习笔记——8.11 实际用户ID、有效用户ID、设置用户ID

    用户ID的基本概念 在Unix系统中,很多操作涉及到权限问题,这些权限涉及到用户ID和组ID的概念.     组ID和用户ID的原理和相关内容是类似的.下面介绍用户ID.     我们常见见到三种关于 ...

  7. Cannot mix incompatible Qt library (version 0x40805) with this library (version 0x40801)

    问题描述 今天运行我的 linux 上的 go 语言 IDE liteide 突然报错,错误如下: Cannot mix incompatible Qt library (version 0x4080 ...

  8. strip()函数和 split()函数

    一:python strip()函数介绍 函数原型:strip可以删除字符串的某些字符 声明:s为字符串,rm为要删除的字符序列 s.strip(rm)        删除s字符串中开头.结尾处,位于 ...

  9. tensorflow 初学习

    tenseroflow 拟合 y = ax*x+b构建神经网络主要分为 4 个步骤:构造数据.构建网络.训练模型.评估及预测模型.此外,还介绍了一些超参数设定的经验和技巧 #coding=utf-8 ...

  10. 模仿python中的range功能

    主要是利用生成器来写的一个函数: def myxrange(start, stop = None, step = 1): #这里的stop一定要等于None,不能等于0,要不然会有好多问题 if st ...