栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

dp解决01背包问题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

dp解决01背包问题

文章目录
  • 前引
  • 一.问题描述
  • 二.解决思路
  • 三.为什么先解决子问题可以最后解决大问题?
  • 四. 完整C++代码


前引

博主现在在面临着七门考试,但今晚得补一个算法作业,在此记录一下解决思路。


一.问题描述

有 N 件物品和一个最多能被重量为 W 的背包。第 i 件物品的重量是 weight[i],得到的价值是 value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。
这里我们把问题具体化:有四件商品,价值依次为 1500,2000,2000,3000,对应的重要依次为1,1,3,4,背包容量为4.


二.解决思路

动态规划: 先解决子问题,再逐步解决大问题
我们的目标是求出在有四件商品可选的情况下,容量为4的背包能装入的最大价值。那么这个问题的子问题是:在有1~4个商品可选的情况下,容量1 ~ 4的背包能装入的最大价值。我们可以表示为以下表格

容量1容量2容量3容量4
(1500,1)1500150015001500
(2000,1)2000350035003500
(2000,3)2000350035004000
(3000,4)2000350035004000

显然表格右下角的数值就是我们最终的答案

按照先遍历物品,再遍历背包重量的思路,具体的求解思路应该是:先求出一件商品可选情况下,背包总 1 ~ 4的最大价值,再求出二件商品可选…逐步求出四件商品可选时,背包容量为4的最大价值


三.为什么先解决子问题可以最后解决大问题?

对于表格的每一项,在第一行仅可选一件商品情况下,背包价值在能装下该商品的情况下,最大价值为该商品价值

if (i == 0 && weight[0]<=j) // i:commodity serial number , j:bagweight
		dp[i][j] = value[0];  // Only one item can be selected

对于表格的其余项,填入的值只有两种选择

  1. 当前商品行的价值 + 背包剩余容量可装下的最大价值

  2. 不选择装入当前行商品,背包内物品最大价值不变

两者取max
显然,当背包容量小于当前商品重量时,必然只能选择第二个

for (int i = 1; i < cdyNum; i++)  // commodity serial number
		for (int j = 1; j <= bagWeight; j++)  // bagweight
		{
			if (j < weight[i])//bagWeight is less than the current row weight, the maximum value will not change
				dp[i][j] = dp[i - 1][j]; 
			else
				dp[i][j] = max(dp[i - 1][j], value[i] + dp[i - 1][j - weight[i]]);
		}

自此我们可以看出,子问题为我们提供了一个信息:背包剩余容量可装下的最大价值,进而我们才可以确定两个选择的值,进而选出最大价值。


四. 完整C++代码

代码中对表格的初始化略显多余,对除第1行第0列的赋值以外均没有必要,但为了避免变量出现不确定值,我还是选择对该部分初始化为0。

#include
#include
#include
using namespace std;

void Solution()
{
	int bagWeight = 4;
	int cdyNum = weight.size(); //number of commondity 
	vectorweight { 1,1,3,4};
	vectorvalue{ 1500,2000,2000,3000};


	vector> dp(cdyNum,vector(bagWeight + 1));// Two-dimensional array

	//initial
	for(int i = 0;i
			if (j == 0)  // bagWeight = 0 ,so total value = 0
				dp[i][j] = 0;
			else if (i == 0 && weight[0]<=j)
				dp[i][j] = value[0];  // Only one item can be selected
			else 
				dp[i][j] = 0;
		}

	// dynamic programming
	for (int i = 1; i < cdyNum; i++)  // commodity serial number
		for (int j = 1; j <= bagWeight; j++)  // bagweight
		{
			if (j < weight[i])//bagWeight is less than the current row weight, the maximum value will not change
				dp[i][j] = dp[i - 1][j]; 
			else
				dp[i][j] = max(dp[i - 1][j], value[i] + dp[i - 1][j - weight[i]]);
			
		}

	//result
	cout <<"the maximum value: "<< dp[cdyNum - 1][bagWeight] << endl;
}


int main()
{
	Solution();
}

咱就把 01 背包问题讲个通透! - 力扣

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/989835.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号