bzoj1017(JSOI2008)魔兽地图
题目: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)魔兽地图的更多相关文章
- [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 【树形dp + 背包dp】
题目链接 BZOJ1017 题解 orz hzwer 树形dp神题 设\(f[i][j][k]\)表示\(i\)号物品恰好花费\(k\)金币,并将\(j\)个物品贡献给父亲的合成时的最大收益 计算\( ...
- BZOJ1017: [JSOI2008]魔兽地图DotR
传送门 设$f[i][j][k]$表示对于第$i$个点,向父节点贡献$j$个已合成的装备,花费了$k$的代价,最多获得的力量值. 单纯的$f[i][j][k]$是很难转移的,主要原因是无法维护和其他儿 ...
- bzoj1017 [JSOI2008]魔兽地图DotR——DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1017 好难想的状态啊!f[i][j][k]表示i号物品有j个向上贡献,一共花了k钱的最大力量 ...
- 【BZOJ1017】[JSOI2008]魔兽地图(动态规划)
[BZOJ1017][JSOI2008]魔兽地图(动态规划) 题面 BZOJ 洛谷 题解 状态设一下,\(f[i][j][k]\)表示第\(i\)个物品,有\(j\)个用于合成,总花费为\(k\)的最 ...
- 【bzoj1017】[JSOI2008]魔兽地图DotR
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1658 Solved: 755[Submit][S ...
- 【BZOJ-1017】魔兽地图DotR 树形DP + 背包
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1566 Solved: 705[Submit][S ...
随机推荐
- 22.线程池之ScheduledThreadPoolExecutor
1. ScheduledThreadPoolExecutor简介 ScheduledThreadPoolExecutor可以用来在给定延时后执行异步任务或者周期性执行任务,相对于任务调度的Timer来 ...
- 17.并发容器之ThreadLocal
1. ThreadLocal的简介 在多线程编程中通常解决线程安全的问题我们会利用synchronzed或者lock控制线程对临界区资源的同步顺序从而解决线程安全的问题,但是这种加锁的方式会让未获取到 ...
- UVALive-4287 Proving Equivalences (有向图的强连通分量)
题目大意:有n个命题,已知其中的m个推导,要证明n个命题全部等价(等价具有传递性),最少还需要做出几次推导. 题目分析:由已知的推导可以建一张无向图,则问题变成了最少需要增加几条边能使图变成强连通图. ...
- day29 主机管理-堡垒机2-原生ssh会话记录
day29课堂代码:https://github.com/liyongsan/git_class/tree/master/day29 课堂笔记: 通过原生Ssh 记录会话1. 在我们自己的堡垒机交互脚 ...
- js排序算法01——冒泡排序
在codewars上面刷题卡住刷不下去了,意识到自己算法方面的不足,准备写一些算法方面的文章,此为一. 冒泡排序是很常见简单的算法了,每次比较任何两个相邻的项,如果第一个比第二个大,则交换他们,就像气 ...
- HTML5页面,用JS 禁止弹出手机键盘
用户点击input的时候: 会默认调出手机软键盘: 场景:文本框获取焦点时,需要禁止手机弹出自带的输入键盘: 解决方案1: 用一个p/div等标签显示内容:然后放一个隐藏的input: (可能的场景: ...
- 009-对象—— 构造方法__construct析构方法__destruct使用方法 PHP重写与重载
<?php /**构造方法__construct析构方法__destruct使用方法 PHP重写与重载 */ //构造方法:当实例化对象时,自动运行的方法 /*class channel{ fu ...
- Linux crontab使用及注意事项
渗透测试中,经常会用到crontab来执行计划任务,从而实现后门程序的隐藏,但crontab有几个坑点还是需要记录一下,方便日后使用时及时查询 1.crontab配置格式 # Example of j ...
- axios如何使用
我们知道,vue2.0以后,vue就不再对vue-resource进行更新,而是推荐axios,而大型项目都会使用 Vuex 来管理数据,所以这篇博客将结合两者来发送请求 1.安装axios cnpm ...
- 正确设置Firefox下载文件文件名的方法
不同的浏览器需要特殊设置,主要是火狐比较特殊,火狐可能给文件名加上“%0d%0a"这样的编码字符(换行的意思).不得不佩服网上的高手,这也能解决. [HttpGet] public File ...