BZOJ1017 [JSOI2008]魔兽地图DotR 【树形dp + 背包dp】
题目链接
题解
orz hzwer
树形dp神题
设\(f[i][j][k]\)表示\(i\)号物品恰好花费\(k\)金币,并将\(j\)个物品贡献给父亲的合成时的最大收益
计算\(f[i][j][k]\)时,我们先枚举合成了x个\(i\)号物品,计算出此时的花费各种金币下最大收益
然后就可以枚举\(j \le x\)和\(k\),更新\(f[i][j][k]\)了
计算最大收益,就把第\(l\)个子树的\(f[s][w * x][v]\)看做第\(l\)个物品的第\(v\)种物品【\(w * x\)是该子树需要提供的的贡献】
做分组背包即可计算出花费各种金币时可得到的最大收益
由于整体的关系不确定,我们将每棵树根拿出来再做一次分组背包即可
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = H[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define cls(s) memset(s,0,sizeof(s))
using namespace std;
const int maxn = 55,maxm = 2005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int H[maxn],ne = 1;
struct EDGE{int to,nxt,w;}ed[maxm];
inline void build(int u,int v,int w){
ed[ne] = (EDGE){v,H[u],w}; H[u] = ne++;
}
int n,m,rt,f[maxn][101][maxm],g[maxn][maxm],h[maxn][maxm];
int W[maxn],P[maxn],M[maxn],typ[maxn],fa[maxn];
void dfs(int u){
if (!typ[u]){
M[u] = min(M[u],m / P[u]);
for (int i = 0; i <= M[u]; i++)
for (int j = 0; j <= i; j++)
f[u][j][i * P[u]] = (i - j) * W[u];
return;
}
M[u] = INF;
Redge(u){
dfs(to = ed[k].to);
M[u] = min(M[u],M[to] / ed[k].w);
P[u] += P[to] * ed[k].w;
}
M[u] = min(M[u],m / P[u]);
memset(g,-0x3f3f3f3f,sizeof(g));
g[0][0] = 0;
for (int x = M[u]; x >= 0; x--){
int tot = 0;
Redge(u){
++tot; to = ed[k].to;
for (int j = 0; j <= m; j++)
for (int v = 0; v <= j; v++)
g[tot][j] = max(g[tot][j],g[tot - 1][j - v] + f[to][ed[k].w * x][v]);
}
for (int j = 0; j <= x; j++)
for (int v = 0; v <= m; v++){
if (v) g[tot][v] = max(g[tot][v],g[tot][v - 1]);
f[u][j][v] = max(f[u][j][v],g[tot][v] + W[u] * (x - j));
}
}
}
int main(){
memset(f,-0x3f3f3f3f,sizeof(f));
n = read(); m = read(); char c;
REP(i,n){
W[i] = read();
c = getchar(); while (c != 'A' && c != 'B') c = getchar();
if (c == 'A'){
typ[i] = 1;
int x = read(),to,w;
while (x--){
to = read(); w = read();
build(i,to,w);
fa[to] = i;
}
}
else P[i] = read(),M[i] = read();
}
int tot = 0;
for (int u = 1; u <= n; u++)
if (!fa[u]){
dfs(u); ++tot;
for (int i = 0; i <= m; i++)
for (int j = 0; j <= i; j++)
h[tot][i] = max(h[tot][i],h[tot - 1][i - j] + f[u][0][j]);
}
int ans = 0;
for (int i = 0; i <= m; i++) ans = max(ans,h[tot][i]);
printf("%d\n",ans);
return 0;
}
BZOJ1017 [JSOI2008]魔兽地图DotR 【树形dp + 背包dp】的更多相关文章
- [BZOJ1017][JSOI2008]魔兽地图DotR 树形dp
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 2597 Solved: 1010[Submit][ ...
- 【BZOJ-1017】魔兽地图DotR 树形DP + 背包
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1566 Solved: 705[Submit][S ...
- BZOJ1017: [JSOI2008]魔兽地图DotR【树形DP】【玄学】
Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...
- [bzoj1017][JSOI2008]魔兽地图 DotR (Tree DP)【有待优化】
Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...
- bzoj1017 [JSOI2008]魔兽地图DotR——DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1017 好难想的状态啊!f[i][j][k]表示i号物品有j个向上贡献,一共花了k钱的最大力量 ...
- BZOJ1017: [JSOI2008]魔兽地图DotR
传送门 设$f[i][j][k]$表示对于第$i$个点,向父节点贡献$j$个已合成的装备,花费了$k$的代价,最多获得的力量值. 单纯的$f[i][j][k]$是很难转移的,主要原因是无法维护和其他儿 ...
- 【bzoj1017】[JSOI2008]魔兽地图DotR
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1658 Solved: 755[Submit][S ...
- BZOJ [JSOI2008]魔兽地图DotR
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1243 Solved: 532[Submit][S ...
- BZOJ1017 魔兽地图DotR (树上背包)
一道背包的神题,用到了树上dp和背包dp,这个题的特殊性在于儿子对于父亲节点是有影响的,所以用f[i][j][k]表示第i号装备,其中用j个来合成上层装备,花费k元所能获得最大的力量值. 然后对于每一 ...
随机推荐
- datatables 给字段设置默认值,屏蔽没有字段的错误
我们返回的数据不能保证都是正常的,可能包含 null ,显然这个对于最终用户来说是不友好的,那么我们可以这么处理 先有如下数据格式: //示例数据 { data:[ {"id":1 ...
- Shell学习——终端打印
1.echo1.1.默认情况下,echo在每次调用后会添加一个换行符1.2.待打印的内容,可以用单引号.双引号或者直接打印,不同的方式,有各自的限制1.2.1.使用不带引号的echo时,没法打印分好( ...
- 【转摘】TFS上分支和标签的用法
引用路径:http://blog.csdn.net/cxzhq2002/article/details/8518250 什么时候用分支: 例如为某个客户定制的专用版本,和主干的特性有很大差别.不具通 ...
- c# .net 3.5 4.0 4.5 5.0 6.0各个版本新特性战略规划总结【转载】
引用:http://blog.csdn.net/attilax/article/details/42014327 c# .net 3.5 4.0 各个版本新特性战略规划总结 1. ---------- ...
- Python__关于列表的引用 以append操作为例
对于列表这样的可变类型来说,对它操作是不会改变内存地址的. 若列表里面存的元素是整数这样的不可变类型,若修改这个元素那地址还是会改变,如: >>> a = [,,] >> ...
- C语言进阶——关于07中指针的补充
首先我们应该了解指针可以分为: 野指针: 野指针不是NULL指针,是未初始化或未清零的指针,他指向的内存地址不是程序员想要的.人们一般不会错用NULL指针,因为用if语句很容易判断.但是“野指针”是很 ...
- 26-dotnet watch run 和attach到进程调试
1-打开vscode, 按下Ctrl+`,打开命令行窗口 创建一个donet core mvc项目 2-打开刚刚创建的文件夹 3-输入 dotnet run 访问网站 4 -F5键即可调试 5-更改代 ...
- 5 Django-1的路由层(URLconf)
URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码 ...
- Hibernate---实体类注释简介
1.类级别注解 @Entity:映射实体类 @Entity(name="tableName") - 必须,注解将一个类声明为一个实体bean. 属性: name - 可选,对应数据 ...
- 斐波那契数列(Fibonacci) iOS
斐波那契数列Fibonacci 斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2 ...