背包问题二(题解)

题目描述

有 N 组物品和一个容量是 V 的背包。

每组物品有若干个,同一组内的物品最多只能选一个。 每件物品的体积是 vij ,价值是 wij ,其中 i 是组号,j 是组内编号。

求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。

输出最大价值。

输入格式

第一行有两个整数 N,V ,用空格隔开,分别表示物品组数和背包容量。

接下来有 N 组数据:

每组数据第一行有一个整数 Si,表示第 i 个物品组的物数量;
每组数据接下来有 Si 行,每行有两个整数 vij, wij,用空格隔开,分别表示第 i 个物品组的第 j个物品的体积和价值;

输出格式

输出一个整数,表示最大价值。

输入输出样例

输入

3 5
2
1 2
2 4
1
3 4
1
4 5

输出

8

说明/提示

0<N,V≤100

0<Si≤100

0<vij,wij≤100

代码: 

/*
	分组背包 
			n , m
			n 物品组
			m 背包体积
			每组物品里面, 有多种物品,(每种物品只有一件)
			给出每组物品里, 每件物品的价值, 体积 
			
			求 从 n 组物品中选, 每组物品最 多选一件物品, 也可以不选
				总体积不超过 m , 总价值最大
				
	f[i, j]
				f[i, j] = k; 
			1. 集合 
					表示: n 组物品中选, 每组物品最 多选一件物品, 也可以不选
						   总体积不超过 m 的所有选法的集合
						
						(属性, 数)存的数是这个集合中的某一个方案, 这个方案总价值最大
						max(价值) 
			
			2. 计算集合
					f[i, j] ---> 包含的子集, 只要找 到所有子集取 Max 
					在这个题里面, 每个子集就是一种方案 
					max(1, 2, 3, 4, ...i);
					
					f[i, j]
					不选 第 i 组的物品
						f[i, j] = max(f[i, j], f[i - 1, j])
						 
					选 第 i 组的物品
						选第 i 组的哪一个物品 
						     k: 第 i 组 物品中第 k 个物品 
						f[i, j] = max(f[i - 1, j - vik] + wik, f[i, j])    
			
		f[i,j] = max(f[i-1,j], f[i-1,j-vi1]+wi1, f[i-1,j-vi2]    +wi2...f[i-1,j-vik]  +  wik)
f[i,j-vi1] = max(f[i-1,j-vi1],f[i-1,j-2vi1]+wi1, f[i-1,j-vi1-vi2]+wi2...f[i-1,j-vi1-vik]+wik) 
			
			3. 边界: f[0, j] = 0;
			
			4. O(n^3)
*/ 

#include <iostream>
using namespace std;
const int N = 110; 
int n, m;
int f[N][N];
int s[N], v[N][N], w[N][N];

int main()
{
	cin >> n >> m;
	
	for (int i = 1; i <= n; i++){
		cin >> s[i];
		for (int j = 1; j <= s[i]; j++)
			cin >> v[i][j] >> w[i][j]; 
	}
	
	for (int i = 1; i <= n; i++)   // 物品组 
		for (int j = 1; j <= m; j++){  // 体积
			f[i][j] = f[i - 1][j];
			for (int k = 1; k <= s[i]; k++)  // 每组物品中的每个物品 
				if (v[i][k] <= j)
					f[i][j] = max(f[i - 1][j - v[i][k]] + w[i][k], f[i][j]); 
		} 
		
	cout << f[n][m] << endl;
	
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值