二维费用的背包问题 以 一本通1271潜水员 为例+规律总结

1271:【例9.15】潜水员

【题目描述】
潜水员为了潜水要使用特殊的装备。他有一个带2种气体的气缸:一个为氧气,一个为氮气。让潜水员下潜的深度需要各种的数量的氧和氮。潜水员有一定数量的气缸。每个气缸都有重量和气体容量。潜水员为了完成他的工作需要特定数量的氧和氮。他完成工作所需气缸的总重的最低限度的是多少?
例如:潜水员有5个气缸。每行三个数字为:氧,氮的(升)量和气缸的重量:
3 36 120
10 25 129
5 50 250
1 45 130
4 20 119
如果潜水员需要5升的氧和60升的氮则总重最小为249(1,2或者4,5号气缸)。
你的任务就是计算潜水员为了完成他的工作需要的气缸的重量的最低值。

【输入】
第一行有2整数m,n(1≤m≤21,1≤n≤79)。它们表示氧,氮各自需要的量。
第二行为整数k(1≤n≤1000)表示气缸的个数。
此后的k行,每行包括ai,bi,ci(1≤ai≤21,1≤bi≤79,1≤ci≤800)3ai,bi,ci(1≤ai≤21,1≤bi≤79,1≤ci≤800)3整数。这些各自是:第i个气缸里的氧和氮的容量及汽缸重量。
【输出】
仅一行包含一个整数,为潜水员完成工作所需的气缸的重量总和的最低值。
【输入样例】
5 60
5
3 36 120
10 25 129
5 50 250
1 45 130
4 20 119
【输出样例】
249

二维费用背包问题 思路:

二维费用的背包问题是指:对于每件物品,具有两种不同的费用,选择这件物品必须同时付出这两种代价。对于每种代价分别为代价1、代价2。在这里设第 i 件物品所需要的两种代价分别为w1[1],w2[i]。两种代价可以付出的最大值(两种背包的容量)分别为m1,m2.物体的价值为c[i]。
算法:费用加了一维,只需要状态增加一维即可。原本的二维数组,可以变成三维的。即 f[i][v][u] 表示考虑前 i 种物品付出代价1为v和代价2为u时能够获得的最大值。
这样以 01背包 为例,状态转移方程就变成了 f[i][v][u] = max( f[i-1][v - w1[i]][u - w2[i]] + c[i],f[i-1][v][u] )。
但是根据我们之前将二维数组压缩成一维数组的思路,我们可以将三维的数组压缩成二维的数组。只不过仍然要注意 " 01背包是从后向前遍历,无后效性;完全背包是从前向后遍历,无限次成倍再考虑"。
物品总个数的限制(一本通书本上提出的):
有时,“二维费用”的条件是以这样一种隐含的方式给出的,最多只能取M件物品,这实际上相当于每件物品多了一种“件数”的费用,每个物品的件数费用均为1,可以付出的最大件数费用为M。也就是f[v][m] 表示付出费用v、最多选m件时可以得到的最大价值。根据物品类型(01、完全、多重)用不同的方法循环更新,最后再f[0…V][0…M]范围内寻找答案。如果要求“恰好取M件物品”,就在f[0…V][M](定义一个维度)的范围内寻找答案。(根据要求选择范围,寻找答案)

本题分析:

潜水员这道题可以看做是二维费用的 01 背包问题。
1、确定价值和代价:所求即为价值——重量。 两种代价,一种代价为含氧量,另一种代价为含氮量。
2、确定寻找范围:题目对两种代价的要求是必须大于等于m1,m2。所以我们可以将大于m1的都放在m1中,将大于m2的都放在m2中,这样对结果没有任何影响。
3、初始化:最后需要求最小,所以一开始将整个二维数组都初始为较大的数。
4、标准的背包问题中,是所装物品的重量不能超过背包能够容纳的重量,所以遍历中是当前单元格是由前面的单元格确定。但是本题中,代价是最小限制,就是物品的对应的量的值必须要大于所给的代价,所以才是借助当前单元格确定后面的单元格。(注意第一个单元格a[0][0]初始化为0,这样

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值