P4037 [JSOI2008] 魔兽地图

比较难的树上背包题目。

题目中装备有购买限制,所以二维树上背包状态肯定无法表示。又由于每件装备的合成只与其子节点的合成数量有关,所以需要一维表示这一个装备合成多少个,这样刚好可以进行父子之间的转移。

设状态 \(f[x][y][z]\) 表示第 \(x\) 件装备合成 \(z\) 个,使用 \(y\) 个金币可以达到的最大价值。

初始时,\(f[x][y][z]\) 为负无穷。对于叶子节点,直接枚举购买数量,计算需要的金币,记录状态。

我们枚举 \(z\),经过手推发现直接转移是不行的,所以考虑记录辅助转移数组 \(g[i][j]\) 表示第 \(x\) 件装备合成 \(z\) 个时,考虑到第 \(i\) 棵子树,使用了 \(j\) 个金币。

我们发现,每一棵子树都必须达到可以合成 \(z\) 个第 \(x\) 件装备的数量。也就是说,第 \(i\) 棵子树的装备至少合成 \(w_{x,i}\times z\) 个,且不能不选,其中 \(w_{x,i}\) 为合成 \(x\) 需要的 \(i\) 的数量。由于不能不选,所以 \(g[i][j]\) 的初值为负无穷,\(g[0][0]=0\)。

接下来,我们使用类似分组背包的转移方式。对于第 \(i\) 棵子树,在合成数量大于 \(w_{x,i}\times z\) 的情况下任意选择,也就是枚举这个子树使用的金币 \(k\),合成的数量 \(l\)。易得如下转移方程:(\(s_{x,i}\) 为第 \(i\) 棵子树对应到的编号)

\[g[i][j]=\max(g[i-1][j],g[i][j-k]+f[s_{x,i}][j][l])(0\le k\le j,w_{x,i}\times z\le l \le 100)
\]

上述过程可以使用滚动数组优化空间。转移结束后,令 \(f[x][y][z]=g[c_x][y]\),其中 \(c_x\) 为 \(x\) 的子树数量,并计算合成的贡献。

这样做复杂度较高,为 \(O(100^2nm^2)\)。我们注意到如果倒序枚举 \(z\),那么对于确定的 \(i,j\),\(f[s_{x,i}][j][l]\) 组成的集合元素数量是单增不降的。我们可以使用一个变量来维护,就不需要枚举 \(l\) 了,时间复杂度为 \(O(100nm^2)\)。

这样还是会超时。我们发现其实对于一些高级装备,它们最多被合成的数量其实不大。我们可以把这个数量预处理出来,记为 \(y_x\),\(z\) 就只需要从 \(y_x\) 枚举到 \(0\) 即可。

经过上述优化,代码成功通过此题。

#include <bits/stdc++.h>
using namespace std;
int n,m,c,x,ind[60],a[60],b[60],t[60],y[60],s[60][60],w[60][60],f[60][2001][101],g[2][2001],mx[60][2001],ans=-1e9;
char op;
void prework(int x)
{
if(t[x]==0)return;
y[x]=1e9;
for(int i=1;i<=t[x];i++)
{
prework(s[x][i]);
y[x]=min(y[x],y[s[x][i]]/w[x][i]);
}
} void dfs(int x)
{
int now=0;
if(t[x]==0)return;
for(int i=1;i<=t[x];i++)dfs(s[x][i]);
for(int i=1;i<=t[x];i++)
for(int j=0;j<=m;j++)
mx[s[x][i]][j]=-1e9;
for(int i=1;i<=t[x];i++)
for(int j=0;j<=m;j++)
for(int p=(y[x]+1)*w[x][i];p<=100;p++)
mx[s[x][i]][j]=max(mx[s[x][i]][j],f[s[x][i]][j][p]);
for(int k=y[x];k>=0;k--)
{
for(int i=1;i<=t[x];i++)
for(int j=0;j<=m;j++)
if(k*w[x][i]<=100)
for(int p=k*w[x][i];p<=min((k+1)*w[x][i],100);p++)
mx[s[x][i]][j]=max(mx[s[x][i]][j],f[s[x][i]][j][p]);
for(int j=0;j<=m;j++)g[now][j]=g[now^1][j]=-1e9;
g[now][0]=0;
for(int i=1;i<=t[x];i++)
{
for(int j=0;j<=m;j++)g[now^1][j]=-1e9;
for(int j=0;j<=m;j++)
for(int p=0;p<=j;p++)
g[now^1][j]=max(g[now^1][j],g[now][j-p]+mx[s[x][i]][p]);
now^=1;
}
for(int i=0;i<=m;i++)
if(g[now][i]!=-1e9)f[x][i][k]=g[now][i]+b[x]*k;
}
} int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
for(int k=0;k<=100;k++)
f[i][j][k]=-1e9;
for(int i=1;i<=n;i++)
{
cin>>a[i]>>op;
if(op=='A')
{
b[i]=a[i];
cin>>t[i];
for(int j=1;j<=t[i];j++)cin>>s[i][j],cin>>w[i][j],ind[s[i][j]]++;
}
else if(op=='B')
{
cin>>c>>x;
y[i]=x;
for(int j=0;j<=x;j++)
if(c*j<=m)f[i][c*j][j]=a[i]*j;
}
}
for(int i=1;i<=n;i++)
if(t[i])
for(int j=1;j<=t[i];j++)b[i]-=a[s[i][j]]*w[i][j];
for(int i=1;i<=n;i++)
if(ind[i]==0)prework(i);
for(int i=1;i<=n;i++)
if(ind[i]==0)dfs(i);
for(int i=1;i<=n;i++)
if(ind[i]==0)
{
for(int j=0;j<=m;j++)
for(int k=0;k<=100;k++)
ans=max(ans,f[i][j][k]);
cout<<ans;
}
return 0;
}

Luogu P4037 [JSOI2008] 魔兽地图 题解的更多相关文章

  1. BZOJ [JSOI2008]魔兽地图DotR

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

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

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

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

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

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

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

  5. 1017: [JSOI2008]魔兽地图DotR - BZOJ

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

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

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

  7. [JSOI2008]魔兽地图(树形dp)

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

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

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

  9. [luogu4037 JSOI2008] 魔兽地图 (树形dp)

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

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

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

随机推荐

  1. Web前端入门第 30 问:CSS 文本与字体样式常用属性

    CSS 盒模型是基石,文本和字体则是盒子内容的重要组成部分.毕竟清水房有了,软装也得跟上啊. 字体常用属性 font-family 定义字体类型(如: Arial, "Microsoft Y ...

  2. Wolfram常用计算

    1.方程与方程组 例1:求解方程 参考表达式: solve x^3 + 2x^2 - 6x + 5 = 0 real 求解所有根 例2:求解方程: 参考表达式: solve ax^2+bx+c=0 注 ...

  3. Avalnoia跨平台实战记录(一),Avalonia初始化

    前言: 记录一下小菜鸟程序员从WPF一知半解转向Avalonia跨平台桌面端开发的一点记录和感想,我个人是比较喜欢用.NET来开发的,当然,这也和我的技术栈有很大关系,本人只是从大专出来的,在学校里学 ...

  4. kafka 基础入门

    kafka是什么 Kafka (Apache kafka is a distributed streaming platform) ,官方定义是一个分布式流式计算平台.在我开发的项目中,是把kafka ...

  5. eolinker取数组数据合并成一个数据的方法

    有时候遇到数据存在某一个数组中,类似下图结构,而用到这些数据的接口又需要一个数据集合,比如这样[14224, 14223]. 思路使用后置脚本,创建一个集合,把这两项数据取出来来,然后放到集合里,脚本 ...

  6. python,去掉“xa0”和“\r\n”

    爬小说网站,输出内容有时候会出现下图字符 首先,去掉"xa0" s = 'T-shirt\xa0\xa0短袖圆领衫,体恤衫\xa0' out = "".join ...

  7. IIS的垃圾回收对后台任务及隐形后台任务的影响

    IIS的垃圾回收引起的影响 错误排查 现象:在.net core api里创建的BackgroundService定义rabbitmq消费的逻辑,在一段时间运行后经常会出现消费任务中断,在日志里找了很 ...

  8. Excel工具类之“参数汇总”

    一.SXSSFWorkbook技术 1.冻结行数 代码 SXSSFWorkbook wb = new SXSSFWorkbook(); SXSSFSheet sheet = wb.createShee ...

  9. 联邦学习图像分类实战:基于FATE与PyTorch的隐私保护机器学习系统构建指南

    引言 在数据孤岛与隐私保护需求并存的今天,联邦学习(Federated Learning)作为分布式机器学习范式,为医疗影像分析.金融风控.智能交通等领域提供了创新解决方案.本文将基于FATE框架与P ...

  10. Django实例(3)-用户连数据库登入系统

    App01--->urls.py from django.contrib import adminfrom django.conf.urls import urlfrom app01 impor ...