【BZOJ】【1017】【JSOI2008】魔兽地图Dotr
树形DP
一开始想:f[i][j]表示以 i 为根的子树,花 j 块钱能得到的最高力量值,结果发现转移的时候没法保证叶子结点的数量限制TAT
只好去膜拜题解了……在这里贴两篇泛型背包的文章吧:《背包九讲》、徐持衡《浅谈几类背包题》
vfk的酷炫姿势没看懂……这篇题解应该讲的是比较清楚的一篇>_> http://blog.csdn.net/baidu_20126217/article/details/40086029
这题算是把我对树形DP的闭塞理解给打通了一点。
我本认为树形DP只有用子节点的状态去更新父节点的状态,真是太天真了。
实际上这道题里是用子节点的状态合并得到父节点的状态。
首先,设出状态f[i][j][k]表示节点i对父亲的贡献为j付出的代价为k时i节点及其子树可以得到的最多能量。
dp当然要从初始状态推起咯。
那么对于那些叶子节点,也就是所谓的基本装备:
f[i][j][j*cost[i]]=(j-i)*power[i]
然而对于那些非叶子节点:
f[i][j][k]=max{g[k-r]+f[son][j*need[son]][r]};
这个方程具体点的解释可以理解为预算为k,拨给这个项目经费为r。
注意在这里我们并没有对f[i][j][k]中这一层中“私吞”部分进行统计,所以是j*need[son],也就是假设全部先上交。
此处g数组是对上一次f[i][j]的复制,防止出现值的误调用。
此处循环考虑的因素比较多,所以总不能一边调用f[i][j]一边更新f[i][j]吧。memcpy多方便。
然后我们开始统计私吞部分:
f[i][j][k]=max{f[i][j'][k]+(j'-j)*power[i]}
事实上,(j'-j)*power[i]就是没有用于合成(即上交)的i装备产生的能量。
非常巧妙,可惜这状态我想不到,还是经验问题。
Tips:注意挖掉一些非法状态和缩小lim范围。
/**************************************************************
Problem: 1017
User: Tunix
Language: C++
Result: Accepted
Time:8236 ms
Memory:48576 kb
****************************************************************/ //BZOJ 1017
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
inline int getint(){
int v=,sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=,INF=~0u>>;
typedef long long LL;
/******************tamplate*********************/
int n,m,ans=-INF;
struct node{int to,v;};
vector<node>G[N];
int f[N][][],g[],cost[N],num[N],str[N],fa[N];
void dfs(int x){
if (!G[x].size()){
num[x]=min(num[x],m/cost[x]);
F(i,,num[x])
F(j,i,num[x])
f[x][i][j*cost[x]]=(j-i)*str[x];
return;
}//DP边界:叶子结点
num[x]=INF;
rep(i,G[x].size()){
dfs(G[x][i].to);
// cost[x]+=cost[G[x][i].to]*G[x][i].v;
num[x]=min(num[x],num[G[x][i].to]/G[x][i].v);
}//预处理合成装备的num和cost
F(i,,num[x]) f[x][i][]=;
rep(i,G[x].size()){
int to=G[x][i].to;
F(j,,num[x]){
memcpy(g,f[x][j],sizeof f[x][j]);
memset(f[x][j],-,sizeof f[x][j]);
D(k,m,){
D(r,k,)
if (g[k-r]!=- && f[to][j*G[x][i].v][r]!=-)
f[x][j][k]=max(f[x][j][k],g[k-r]+f[to][j*G[x][i].v][r]);
ans=max(ans,f[x][j][k]);
}
}
}
F(i,,num[x]) F(j,i,num[x]) F(k,,m)
if (f[x][j][k]!=-)
f[x][i][k]=max(f[x][i][k],f[x][j][k]+(j-i)*str[x]),
ans=max(ans,f[x][i][k]);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("1017.in","r",stdin);
freopen("1017.out","w",stdout);
#endif
n=getint(); m=getint();
F(i,,n){
fa[i]=i;
num[i]=INF;
cost[i]=;
}
char s1[];
F(i,,n){
str[i]=getint();
scanf("%s",s1);
if (s1[]=='B'){
cost[i]=getint();
num[i]=getint();
}else{
int c=getint();
F(j,,c){
int x=getint(),y=getint();
G[i].pb((node){x,y});
fa[x]=i;
}
}
}
int root=;
F(i,,n) if (fa[i]==i){root=i;break;}
memset(f,-,sizeof f);
dfs(root);
printf("%d\n",ans);
return ;
}
【BZOJ】【1017】【JSOI2008】魔兽地图Dotr的更多相关文章
- bzoj 1017: [JSOI2008]魔兽地图DotR【树形dp+背包】
bzoj上是一个森林啊--? dp还是太弱了 设f[i][j][k]为到点i,合成j个i并且花费k金币能获得的最大力量值,a[i]为数量上限,b[i]为价格,p[i]为装备力量值 其实这个状态设计出来 ...
- bzoj 1017 : [JSOI2008]魔兽地图DotR
比较难想的的一道树形dp. 看到这道题正常的思路应该是$f[i][j][k]$表示i这棵子树里买了j个i物品花费为k的最大收益. 但如果直接这么定义的话转移复杂度会很高,需要枚举j,枚举孩子,枚举k, ...
- 1017: [JSOI2008]魔兽地图DotR - BZOJ
Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...
- BZOJ.1017.[JSOI2008]魔兽地图(树形DP 背包DP)
题目链接 树形DP,考虑子节点对父节点的贡献. 设f[x][i][j]表示当前为x,用i个x去合成上一层装备,花费为j的最大价值. 由子节点转移时 是一个分组背包,需要一个辅助数组g[i][j]表示前 ...
- BZOJ [JSOI2008]魔兽地图DotR
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1243 Solved: 532[Submit][S ...
- 【bzoj1017】[JSOI2008]魔兽地图DotR
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1658 Solved: 755[Submit][S ...
- [BZOJ1017][JSOI2008]魔兽地图DotR 树形dp
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 2597 Solved: 1010[Submit][ ...
- [bzoj1017][JSOI2008]魔兽地图 DotR (Tree DP)【有待优化】
Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...
- BZOJ1017: [JSOI2008]魔兽地图DotR【树形DP】【玄学】
Description DotR (Defense of the Robots) Allstars是一个风靡全球的魔兽地图,他的规则简单与同样流行的地图DotA (Defense of the Anc ...
- BZOJ1017: [JSOI2008]魔兽地图DotR
传送门 设$f[i][j][k]$表示对于第$i$个点,向父节点贡献$j$个已合成的装备,花费了$k$的代价,最多获得的力量值. 单纯的$f[i][j][k]$是很难转移的,主要原因是无法维护和其他儿 ...
随机推荐
- js获取和设置DOM样式函数cssStyle(类似于jquery的$(elem).css())
如题,相信这个函数百度一搜一大推,但令人匪夷所思的是这些函数都写的“奇形怪状的”,例如http://www.cnblogs.com/windows7/archive/2010/03/30/170064 ...
- Spark RDD的依赖解读
在Spark中, RDD是有依赖关系的,这种依赖关系有两种类型 窄依赖(Narrow Dependency) 宽依赖(Wide Dependency) 以下图说明RDD的窄依赖和宽依赖 窄依赖 窄依赖 ...
- Linux rabbitmq的安装和安装amqp的php插件
RabbitMQ是一个消息代理.它的核心原理非常简单:接收和发送消息.你可以把它想像成一个邮局:你把信件放入邮箱,邮递员就会把信件投递到你的收件人处.在这个比喻中,RabbitMQ是一个邮箱.邮局.邮 ...
- How to get Financial Dimension Value from Worker Position[AX2012]
To get financial dimension value from worker position, add a new method in hcmWorker Table with scri ...
- Linux平台下:块设备、裸设备、ASMlib、Udev相关关系
对磁盘设备(裸分区)的访问方式分为两种:1.字符方式访问(裸设备):2.块方式访问 Solaris平台 : 在Solaris平台下,系统同时提供对磁盘设备的字符.块方式访问.每个磁盘有两个设备文件名: ...
- ok6410的LCD裸机范例
/****************************************** 实验步骤 1.配置引脚功能,将其GPI.GPJ引脚设置为VD数据输出模式,及GPJ后几位设置成LCD时钟输出: ...
- EMVTag系列11《电子现金发卡行授权码》
按照银联个人化模板的建议,如卡片支持非接触快速支付应用(qPBOC),则推荐将电子现金授权码(9F74)作为qPBOC 应用AFL列表中的最后一条记录,且最后一条记录仅包含该数据元. 原因是:在某些情 ...
- hdu 1872 稳定排序
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1872 稳定排序 Description 大家都知道,快速排序是不稳定的排序方法.如果对于数组中出现的任 ...
- hdu 1622 Trees on the level
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1622 小白书上的题... #include<algorithm> #include< ...
- 如何从官网下载springframework和document
spring官网 http://spring.io/ --->spring project--->点击github图标 --->artifactory --->进入到了http ...