问题描述
有N件物品和一个容量是V的背包,每组物品有若干个,同一组内的物品最多只能选一个,每件物品的体积是vij,价值是wij,求解将哪些物品装入背包可以使物品的总体积不超过背包容量,且总价值最大,输出最大价值。
输入格式及输出格式
输入格式:第一行两个整数,表示物品数量和背包容积,接下来有N行,每组数据第一行有一个整数si,表示第i个组的物品数量,接下来si行,每行有两个整数vij和wij,表示第i个物品组的第j个物品的体积和价值。
输出格式:输出一个整数,表示最大价值
基本思想
这题在01背包的问题上,新增了组的限制,所以只需要加一层循环用于在组中选取数据即可,优化思维和01背包问题一致。关于从前遍历还是从后遍历是大家比较关注的一个点,其实只需要记住:当前数组是要用到前一层的数据,则从后往前,反之从前往后。
代码实现
由上述分析,可得代码如下
#include <iostream>
using namespace std;
const int N = 110;
int n, m;
int v[N][N], w[N][N], s[N], f[N];
int main(){
cin >> n >> m;
for (int i = 1; i <= n; i ++ ) {
cin >> s[i];
for (int j = 0; j < s[i]; j ++ )
cin >> v[i][j] >> w[i][j];
}
for (int i = 1; i <= n; i ++ )
for (int j = m; j >= 0; j -- )
for (int k = 0; k < s[i]; k ++ )
if (v[i][k] <= j)
f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);
cout << f[m] << endl;
return 0;
}
任何错误,欢迎指正,Thanks♪(・ω・)ノ