背包九讲(三)——多重背包问题

背包九讲(三)——多重背包问题

参考了著名的背包九讲,可以在这里下载,绪前一篇的完全背包问题

1.1 问题

N种物品和一个容量为V的背包,每种物品都有 M i M_i Mi件可用,放入第i件物品的费用是 C i C_i Ci,得到的价值是 W i W_i Wi。求解将哪些物品装入背包可使价值综合最大。

1.2 解题思路

如果看过之前的完全背包问题,这里的多重背包问题应该就能秒杀了,当时考虑过将完全背包转化为01背包问题求解,而多重背包其实就是加了限制的完全背包,当然也能转化为01背包问题。

方法是:将第 i 种物品分成若干件01背包中的物品,其中每件物品有一个系数。这件物品的费用和价值均是原来的费用乘以这个系数。令这些系数分别为 1 , 2 , 2 2 , . . . , 2 k − 1 , M i − 2 K + 1 1, 2, 2^2, ..., 2^{k-1}, M_i - 2^K+1 1,2,22,...,2k1,Mi2K+1,其中 k 是满足 M i − 2 k + 1 > 0 M_i - 2^k + 1>0 Mi2k+1>0的最大整数(其实就是保证系数和等于 M i M_i Mi)。举个栗子, M i M_i Mi为13,则相应的 k = 3 k = 3 k=3,所有系数为1,2,4,6。

1.3 示例代码

懒得写了~还得自己造数据,和01背包问题代码类似的

1.4 实战阶段

做几道题吧~

洛谷P1776 宝物筛选

题目描述

终于,破解了千年的难题。小 FF 找到了王室的宝物室,里面堆满了无数价值连城的宝物。

这下小 FF 可发财了,嘎嘎。但是这里的宝物实在是太多了,小 FF 的采集车似乎装不下那么多宝物。看来小 FF 只能含泪舍弃其中的一部分宝物了。

小 FF 对洞穴里的宝物进行了整理,他发现每样宝物都有一件或者多件。他粗略估算了下每样宝物的价值,之后开始了宝物筛选工作:小 FF 有一个最大载重为 W 的采集车,洞穴里总共有 n 种宝物,每种宝物的价值为 v i v_i vi,重量为 w i w_i wi,每种宝物有 m i m_i mi件。小 FF 希望在采集车不超载的前提下,选择一些宝物装进采集车,使得它们的价值和最大。

输入输出格式以及样例跳过,请参考原题~


其实非常简单,就是多重背包吧,和上面的思路一样,就是在01背包问题的基础上加了一层循环,直接上代码(附有注释!)

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int main() {
    
    
	cin.sync_with_stdio(false), cin.tie(NULL);
	int n, wSum, k;
	cin >> n >> wSum;
	int* v = (int*)malloc(n * sizeof(int));	// 价值
	int* w = (int*)malloc(n * sizeof(int));	// 重量
	int* m = (int*)malloc(n * sizeof(int));	// 数量
	int* dp = (int*)malloc((wSum+1) * sizeof(int));

	memset(dp, 0, (wSum + 1) * sizeof(int));
	for (int i = 0; i < n; i++) {
    
    
		cin >> v[i] >> w[i] >> m[i];
	}
	for (int i = 0; i < n; i++) {
    
    
		for (k = 1; k < (m[i]+1)/2; k*=2) {
    
    		// 穷举前面的二进制项系数
			for (int j = wSum; j >= k * w[i]; j--) {
    
    
				dp[j] = max(dp[j], dp[j - k * w[i]] + k * v[i]);
			}
		}
		k = m[i] - k + 1;		// 最后一个系数,保证系数和为m[i]
		for (int j = wSum; j >= k * w[i]; j--) {
    
    
			dp[j] = max(dp[j], dp[j - k * w[i]] + k * v[i]);
		}
	}
	cout << dp[wSum] << endl;
	free(v);
	free(w);
	free(dp);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44338712/article/details/109117552