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的最大数量。
相当于一个后缀最大值。
就可以轻松转移了。
虽然复杂度还是有些高。(貌似存在复杂度更低的算法?)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
int n,m;
int f[][][];
int g[][];
int v[],cost[],l[];
int head[],ver[],nxt[],tot,quan[];
void add(int a,int b,int c)
{
tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;quan[tot]=c;return ;
}
bool vis[];
void dfs(int x)
{
if(!head[x])
{
l[x]=min(l[x],m/cost[x]);
for(int i=;i<=l[x];i++)
{
for(int j=;j<=i;j++)
{
f[x][j][i*cost[x]]=i*v[x];
}
}
return ;
}
l[x]=inf;
for(int i=head[x];i;i=nxt[i])
{
dfs(ver[i]);
l[x]=min(l[x],l[ver[i]]/quan[i]);
cost[x]+=cost[ver[i]]*quan[i];
}
l[x]=min(l[x],m/cost[x]);
memset(g,0xcf,sizeof(g));
g[][]=;
for(int i=l[x];i>=;i--)
{
int cnt=;
for(int j=head[x];j;j=nxt[j])
{
cnt++;
for(int k=;k<=m;k++)
{
for(int l=;l<=k;l++)
{
g[cnt][k]=max(g[cnt][k],g[cnt-][l]+f[ver[j]][i*quan[j]][k-l]-v[ver[j]]*(i*quan[j]));
}
}
}
for(int j=;j<=m;j++)
{
f[x][i][j]=g[cnt][j]+i*v[x];
if(i!=l[x])f[x][i][j]=max(f[x][i][j],f[x][i+][j]);
}
} return ;
}
int main()
{
scanf("%d%d",&n,&m);
memset(f,0xcf,sizeof(f));
for(int i=;i<=n;i++)
{
scanf("%d",&v[i]);
char s[];scanf("%s",s);
if(s[]=='A')
{
int num;
int t1,t2;
scanf("%d",&num);
for(int j=;j<=num;j++)
{
scanf("%d%d",&t1,&t2);
vis[t1]=;
add(i,t1,t2);
}
}
else
{
scanf("%d%d",&cost[i],&l[i]);
}
}
int root=;
for(int i=;i<=n;i++)
{
if(!vis[i])add(,i,);
}
dfs(root);
int ans=;
for(int i=;i<=m;i++)ans=max(ans,f[root][][i]);
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]为装备力量值 其实这个状态设计出来 ...
- 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]$是很难转移的,主要原因是无法维护和其他儿 ...
随机推荐
- 学习笔记 | treap | splay
目录 前言 treap 它的基本操作 前言 不会数据结构选手深深地感受到了来自treap的恶意QwQ 在听的时候感觉自己听得听懂的??大概只是听懂了它的意思 代码是怎么写都感觉写不好╮(╯﹏╰)╭ 菜 ...
- Ruby知识点一:方法
1.实例方法 接收者是对象本身的方法 2.类方法 接收者是类本身的方法,调用类方法时,可以使用::或者.两个符号. 类名.方法名 类名::方法名 3.函数式方法 没有接收者(接收者省略而已)的方法 4 ...
- Linux虚拟机安装教程
必备组件: vmware(程序主题) 链接:https://pan.baidu.com/s/14OplOGOQTVAnf0iDqgDhDQ 提取码:jape centos(Linux系统) 链接:ht ...
- Linux 系统安全检查(shell)
脚本内容: #!/bin/bash echo " (__)" echo " (oo)" echo " /------\/ " echo &q ...
- trustbox文件破解
常见的破解方式,是要还原内容的二进制文件,删除加密壳部分的对应二进制数值,然后把剩下的内容保存下来,就实现了破解的任务. 淘宝破解链接:https://item.taobao.com/item.ht ...
- 关于SQL while 循环嵌套 外部循环数据无法进入内部循环
下面一般是,作为SQL新手第一次写循环嵌套的办法,但是大家会发现一个问题,那就是变量@i总是不能进入第二个循环. declare @i int ,@j int, @k int set @j = 1 - ...
- teamwork 2
1.访问上学期项目团队,学习他们的得失. 上学期学长们有一个项目是学霸系统,在看过了学长们的相关博客后,我们可以感受到学长们确实花费了不少心思,也看到了许多值得我们学习的地方. 首先,学长们在项目开始 ...
- Software Defined Networking(Week 2, part 2)
History of SDN 1.3 - 1.4 课程地址 Network Virtualization 网络可虚拟化,可以说是SDN的一项核心内容,同样也源自很多先前的技术和思想.我们先讨论何为网络 ...
- lintcode-514-栅栏染色
514-栅栏染色 我们有一个栅栏,它有n个柱子,现在要给柱子染色,有k种颜色可以染. 必须保证不存在超过2个相邻的柱子颜色相同,求有多少种染色方案. 注意事项 n和k都是非负整数 样例 n = 3, ...
- Arduino Leonardo读取DHT22温湿度传感器
首先在该地址下载库:https://codeload.github.com/nethoncho/Arduino-DHT22/zip/master 使用以下代码测试: /**************** ...