开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天,点击查看活动详情
今天进行二维背包的基础模型学习。
二维费用的背包问题
题目描述
有 件物品和一个容量是 的背包,背包能承受的最大重量是 。
每件物品只能用一次。体积是 ,重量是 ,价值是 。
求解将哪些物品装入背包,可使物品总体积不超过背包容量,总重量不超过背包可承受的最大重量,且价值总和最大。
输出最大价值。
输入格式
第一行三个整数,, 用空格隔开,分别表示物品件数、背包容积和背包可承受的最大重量。
接下来有 行,每行三个整数 ,用空格隔开,分别表示第 件物品的体积、重量和价值。
输出格式
输出一个整数,表示最大价值。
数据范围
输入样例
4 5 6
1 2 3
2 4 4
3 4 5
4 5 6
输出样例
8
题目分析
这是一道二维背包模型的问题。
首先分析题目,每件物品的数量为 ,则可以联想到 01背包的解法。
01背包的转移方程为:
相较于01背包中的物品,二维背包中每个物品除体积外还多了个重量的属性,背包也给出了总体积和总重量两个限制条件。
我们注意到,每件物品的重量和体积是绑定在一起的,即若不选择这件物品,背包在减去相应体积的同时也会减去相应的重量。
自然的,我们可以多开一维数组给重量,转移方程为:
同样,可以像01背包那样压缩一维,转移方程简化为:
时间复杂度为 。
Accept代码 O(vm)
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int f[N][N];
int main()
{
int n, v, m;
cin >> n >> v >> m;
for (int i = 0; i < n; i ++)
{
int a, b, c;
cin >> a >> b >> c;
for (int j = v; j >= a; j --)
for (int k = m; k >= b; k --)
f[j][k] = max(f[j][k], f[j - a][k - b] + c);
}
cout << f[v][m];
return 0;
}