动态规划——0-1背包问题

这篇博客介绍了如何使用动态规划算法解决0-1背包问题。甲有5件行李,每件有不同的重量和效益,需在不超过20公斤的限制下选择行李以最大化效益。算法设计思路包括初始化、遍历决策过程、记录选择等步骤,最终得出最大效益和选择的行李。伪码和源码展示了算法的实现过程,并分析了其时间复杂度为O(nk),空间复杂度同样为O(nk)。
摘要由CSDN通过智能技术生成

甲打算出去旅游,被告知最多可携带20公斤重的行李(可认为甲的行李箱最大承重为20公斤),已知甲拟携带的5件(可认为此案例的规模n=5)行李的重量及其在旅行中产生的效益如表所示:
拟携带行李数量n为5时的0-1背包问题示例:
在这里插入图片描述
那么,为使所携带的行李能在旅行中产生最大效益,请问甲应该带哪几件行李?
本题要求:请设计一个动态规划算法,通过该算法的运行结果来回答“甲应该携带的行李是哪几件”的问题;此外,在算法设计过程中,请采用数组V[i][j]表示从前i (1≤i≤n)个行李中取出行李,并装入剩余负重为j公斤的行李箱时所带来的最大效益。

算法设计思路

设有n件行李,每件行李i(1<=i<=n)的重量和效益分别为w[i]、m[i],背包承重为k,v[i][j]表示从1到i件行李拿出装进最大承重为j的背包的效益最大的选择,0<=i<=n ,0<=j<=k。
①当i为0时,即一件行李也不装,v[0][j]均为0,当j为0时,即背包承重为0,v[i][0]均为0。
②接下来逐个遍历i、j,对于1到i个行李,进行判断,若第i个行李的重量大于j,即w[i]>j,那么背包肯定装不下,此时最优效益情况为前i-1个行李装进容量为j的背包,即v[i][j]= v[i-1][j],若此时背包容量j>w[i],即此时背包可以装下第i件行李,那么要对装不装第i件行李做一个判断:
a.若装下第i件行李,那么要找到剩下空间装下其他第1到i-1件行李的最大效益选择,即m[i]+ v[i-1][j-w[i]]。
b.若不装下第i件行李,那么此时的最大效益选择为上述所示的v[i-1][j]。
对于a、b这两种情况,v[i][j]是当前情况的最大效益选择,因此取这两种情况中的最大值,即最大效益。
④对于最终的最大效益选择,即带1到n件行李装进承重为k的背包的最大效益选择,即v[n][k]就是大效益。
⑤对于最大效益的行李选择,可以通过对每一次的选择进行记录,最后再在最大效益中将所需的行李拿出。在二维数组v中进行操作,增加一个维数,变为v[n+1][k+1][2],即前两个维数表示从0到n的行李选择和0到k的背包承重选择,最后一个维数的0表示当前选择的最大效益,1表示当前选择中第i件行李拿不拿,当进行到④时,拿到了最大效益选择v[n][k][0],若v[n][k][1]=0,即当前选择不包括第n件行李,那么最大效益v[n][k][0]= v[n-1][k][0],然后对v[n-1][k][0]继续判断;若v[n][k][1]=1,即当前选择包括第n件行李,那么先拿出第n件行李,再对剩下的行李和背包空间进行判断,即v[n-1][k-w[n]][0],直到背包承重为0。
⑥还有特殊情况,要考虑当效益最大时的多种可能性,因为可能出现不同选择下都可以达到最大效益,当出现这种情况时,做另外标记,即v[i][j][1]=2,当第一遍输出所需行李时,记录此时最深的一个分歧点,然后进行第二遍输出,遇到该分歧点就转向另一条路,此时再记录下一个分歧点,直到找不到分歧点为止。这样一来,就能输出所有的可能性。

算法实现的伪码

函数:Knapsack(v, n, k)

输入:三维数组v,行李件数n,背包最大承重k,行李各自重量w和效益m

输出: 最大行李效益以及此时行李的选择

S1: for i ← 1 to n//对于行李件数i

S2: for j ←1 to k//对于背包承重j

S3: if w[i] > j//当前行李重量大于背包承重

S4: then v[i][j][0] ← v[i-1][j][0]//当前最佳选择

S5: v[i][j][1] ← 0//当前最佳选择不包括行李i

S6: elseif v[i-1][j][0] = v[i-1][j-w[i]][0]+m[i]//分歧点

S7: Then v[i][j][0] ← v[i-1][j][0]//当前最佳选择

S8: v[i][j][1] ← 2//当前最佳选择有分歧

S9: Elseif v[i-1][j][0] > v[i-1][j-w[i]][0]+m[i]//比较最大效益

S10: then v[i][j][0] ← v[i-1][j][0]//当前最佳选择

S11: v[i][j][1] ← 0//当前最佳选择不包括行李i

S12: else v[i][j][0] ← v[i-1][j-w[i]][0]+m[i]//当前最佳选择

S13: v[i][j][1] ← 1//当前最佳选择包括行李i

S14: return v//返回包含所求信息的的v

算法实现的源码

import java.util.Scanner;

public class Main {
   

	public static void main(String[] args) {
   
		Scanner in = new Scanner(System.in);
		System.out.println("请输入行李件数:");
		int n = in.nextInt();
		System.out.println("请输入背包最大承重:");
		int k 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值