趣味算法------多重背包问题

目录

​编辑

前言

例题

解题思路

具体代码

优化和注意事项


前言

        多重背包问题是组合优化问题的一种,它是经典背包问题的扩展。在多重背包问题中,每种物品都有一个固定的数量限制,即可以被选择放入背包的次数是有限的。问题的目标是在背包容量限制下,选择物品组合以最大化总价值。多重背包问题可以通过动态规划算法解决,但由于物品数量的限制,其状态转移方程和时间复杂度可能会比标准的0-1背包问题复杂。在实际应用中,多重背包问题的解决方案可以通过二进制优化等技术来提高效率. 

        这篇算法是根据上一章01背包问题算法优化而来:

趣味算法------单一背包问题(01背包问题)贪心算法解决-CSDN博客

例题

题目描述
有 N  件物品和一个容量是 V 的背包。每件物品可以多次选用。
第 i 件物品的体积是 vi ,价值是 wi 。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。

输入输出格式
输入格式
第一行两个整数N,V,用空格隔开,分别表示物品数量和背包容积。
接下来有 N 行,每行两个整数 vi wi,用空格隔开,分别表示第 i 件物品的体积和价值。
输出格式
一个非负整数,代表结果。

输入输出样例1
输入
4 5
1 2
2 4
3 4
4 5
输出
10

输入输出样例2
输入
1 2
2 2
输出
2

解题思路

  1. 初始化:代码首先读取背包的容量(V)和物品的数量(N),并初始化一个二维数组 lst 作为动态规划表,以及两个一维数组 weights 和 values 来存储物品的重量和价值。

  2. 读取输入:代码接着读取每个物品的重量和价值,并存储在 weights 和 values 数组中。

  3. 状态转移方程:动态规划表 lst 的状态转移方程是根据经典的0-1背包问题的状态转移方程进行修改的。对于每个物品 i 和背包容量 j,状态转移方程考虑了两种情况:不包含当前物品 i 的最大价值(lst[i - 1][j])和包含当前物品 i 的最大价值(lst[i - 1][j - weights[i - 1]] + values[i - 1])。如果当前物品的重量小于或等于背包容量,就选择这两种情况中的较大者作为 lst[i][j] 的值。

  4. 填充动态规划表:代码通过两个嵌套循环来填充动态规划表 lst。外层循环遍历物品,内层循环遍历背包容量。在每次迭代中,根据状态转移方程更新 lst[i][j] 的值。

  5. 输出结果:最后,代码输出动态规划表中的最终值 lst[N][V],这是在背包容量限制下可以获得的最大价值。

具体代码

​
#include<stdio.h>
#include<stdlib.h>
#define maxlen 100
int main(void)
{
	int N, V;
	scanf("%d%d", &N, &V);
	int lst[maxlen][maxlen] = { 0 };
	int* weights = (int*)malloc(N * (sizeof(N)));
	int* values = (int*)malloc(N * (sizeof(N)));
	for (int i = 0; i < N; i++)
	{
		int w, v;
		scanf("%d%d", &w, &v);
		weights[i] = w;
		values[i] = v;
	}
	for(int i = 1;i<=N;i++)
		for (int j = 0; j <= V; j++)
		{
			if (j < weights[i - 1])
				lst[i][j] = lst[i - 1][j];
			else
			{
				int num1 = lst[i - 1][j];
				int num2 = lst[i][j - weights[i - 1]] + values[i - 1];
				if (num1 > num2)
					lst[i][j] = num1;
				else
					lst[i][j] = num2;
			}
		}
	printf("%d", lst[N][V]);
	return 0;
}

​

优化和注意事项

  • 代码中的状态转移方程是针对多重背包问题进行了调整的,以考虑每个物品可以选择的数量限制。
  • 动态规划表的初始化是从 lst[0][0] 开始的,这是一个空背包的情况,其价值为0。
  • 代码没有进行内存释放,这在实际编程中是一个好习惯,尤其是当使用 malloc 或 calloc 分配内存时。
  • 代码中的循环边界条件是正确的,外层循环从1开始,内层循环从0开始,这是因为数组索引通常从0开始。

这段代码提供了一个直接解决多重背包问题的动态规划方法,它的时间复杂度和空间复杂度都是 O(N*V),其中 N 是物品的数量,V 是背包的容量。这种方法适用于物品数量和背包容量不是特别大的情况。对于更大规模的问题,可能需要考虑更高效的算法或优化技术。

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值