背包问题秒懂-附牛客网真题实战

目录

前言 (很重要)

什么是背包问题 

代码解释 

图文解释(计算机的运行过程)

牛客网真题实战

结束语


前言 (很重要)

        大家好,小张今天开始开启了一个全新的专栏,在这个专栏里的话主要是讲一些重要的算法以及我们可以运用这些算法进行刷题的题目。那么今天给大家带来的是我们在平常在刷算法题的时候经常会用到,或者我们将来面试的时候经常会被问到的一个问题,它就是背包问题(DP)。现在网络上大部分背包问题的讲解很多都只是以代码为基础进行讲解,并没有进行图文解释,所以就会导致大家在看完代码解释之后,会陷入一种有些迷茫的状态,不是很理解这串干巴巴的代码是如何在计算机中工作的。所以我今天就用代码加图文解释的方法助大家理解背包问题,希望大家能够耐下心把这篇文章看完,我相信大家一定会有所收获的! 那么下面我们就来说说背包问题。 

        有很多小伙伴们在学习算法的时候,去学习一些关于算法理论的知识,并不知道自己的代码实战能力如何,也不清楚到底对该算法的了解有多深,所以在这里小张给大家推荐一个很棒的平台,在这里有很多的面试和算法题,也有很多的面试和求职的机会,大家可以点击下方链接进入牛客网刷算法真题,提高自己能力!点击这里刷算法和面试真题提高实战能力

什么是背包问题 

        什么背包问题呢,背包问题可以大致解释为:给定一组物品,每种物品都有自己的体积和价值,在我们规定的总体积内,我们该如果选择,才能使得物品的总价值最高。

        背包问题可以分为 :01背包问题,完全背包问题以及多重背包问题。其中最为重要的就是01背包问题,因为01背包问题是所有背包问题的基础,熟练掌握了01背包问题的思想。我们就能够为理解其他类型的背包问题打下夯实的基础,才能够更好快速的去理解完全背包问题以及多重背包问题。 

代码解释 

         首先是代码部分,在进行解决01背包问题的时候,我们通常需要进行定义一个二维数组即int dp[i][j]。这个dp数组其实就相当于我们的背包,而dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。我们现在理解了这个数组的含义后,我们就开始考虑这个以下问题:①背包能装下物品和不能装下物品,②放物品和不放物品。我们知道在这个背包中 "j"是背包的容量,当我们此时背包的容量小于我们物品的容量时,我们此时该物品一定是放不下的,所以此时我们的dp[i][j] = dp[i - 1][j]这块代码的意思就是说我们此时知道我们的背包是放不下这个物品了,那么我们就跳到下一个物品。如果我们此时的背包容量是大于我们的物品容量的话,我们就该考虑是否要放这个物品,如果不放的话,我么此时的dp[i][j] = dp[i - 1][j],是因为如果我们不进行放的话,我们就要跳到下一个物品。当我们要放的话,此时的dp[i][j] = d[i - 1][j - v[i]] + value[i],意思就是说我们要是放该物品的话,我们就要在背包中减去该物品的容量,而且需要跳过该物品。因为我们需要保证我们此时在背包里放的始终有最大的价值,所以我们还需要在放与不放之间选取最大值,即max(dp[i][j] = dp[i - 1][j], dp[i - 1][j - v[i]] + value[i])。

        下面是运用代码来进行解释我们上方的语言:

if(j < v[i])
{
    dp[i][j] = dp[i - 1][j];
}
else
{
    dp[i][j] = max(dp[i][j] = dp[i - 1][j], dp[i - 1][j - v[i]] + value[i]);
}

图文解释(计算机的运行过程)

 

 

         因为当我们编号为0时候的物品的容量和价值都是0,所以我们将第一行和第一列初始化为0,我们开始进行分析dp[1][1]位置的值,我们由图表可知,我们物品1的体积(容量)为2,价值为3。当我们在此位置的时候我们背包的容量是1,此时放不下该物品,根据我们上方的代码解释我们知道当我们放不下该物品的时候,我们的dp[i][j] = dp[i - 1][j],所以此时在该位置的价值为上方的值为0。

        此时我们来到了dp[1][2]的位置 ,由图表可知,我们物品1的体积(容量)为2,价值为3,此时的背包容量是3,则可以放下。那么我们此时开始进行判断,当我们不放的话,我们的dp[i][j] = dp[i - 1][j],即dp[1][2] = dp[0][2] = 0。当我们放的话,我们此时的dp[i][j] = d[i - 1][j - v[i]] + value[i],即dp[0][0] + 3 = 3。再从放与不放之间取最大值,3 > 0,则此时dp[1][2] = 3。

        后面的值都是由上方的方法推出来的,我相信大家已经理解了,在这里就不再进行解释了。紧接着我们来到了dp[2][3]的位置,此时的背包容量为3, 我们物品2的体积为3,价值为4。那么就刚好可以放下,我们继续进行判断。当我们不放的话,我们的dp[i][j] = dp[i - 1][j],即dp[2][3] = dp[1][3] = 3。当我们放的话,我们此时的dp[i][j] = d[i - 1][j - v[i]] + value[i],即dp[1][0] + 4 = 4。再从放与不放之间取最大值,4 > 3,则此时dp[2][3] = 4。

 

        后面的所有值都是由上方的方法推理而出的, 大家可以自行推理一下,再对照一下表格看看推出来的值对不对

牛客网真题实战

         牛客网是一个集刷题,面试,求职等许多方面为一体的一个综合性的一个平台,在里面有许多的面试真题和算法编程真题点击这里进入牛客网刷算法和面试真题

        大家首先点入这个上方蓝色的链接 ,点进去之后显示这个页面

点击此处的在线编程

再点击算法入门

 在第四部分就是我们的背包问题,除此之外,这里还有很多的算法题和面试真题供大家练习,是一个很好的平台

        这是我们背包问题的题目,我们可以通过在线编程的形式进行解答,那为什么我们要练习在线编程呢,是因为现在随着社会的发展,我们在进行面试或者其他类型的测试的时候,很多的时候用的就是在线编程我方式,所以说我们在平时练习的时候就应该多多进行尝试在线编程的形式,对我们的有很大的帮助,而且在牛客网的在线编程上面拥有代码补齐和断点调试的功能,方便我们进行书写和测试,是一个很棒的在线编程平台!

        因为我们这里只进行的是01背包的问题的解释,所以我们这里只对该题第一问进行代码解答。 

#include<bits/stdc++.h>
using  namespace std;
const int MAX = 1010;
int num = 0, v = 0, v1[MAX], value[MAX], dp[MAX][MAX];

int main()
{
	int max2 = 0, max1 = 0;
	cin >> num >> v;
	for (int i = 1; i <= num; i++)
	{
		cin >> v1[i] >> value[i];
	}
	for (int i = 1; i <= num; i++)
	{
		for (int j = 1; j <= v; j++)
		{
			if (v1[i] > j)
			{
				dp[i][j] = dp[i - 1][j];
			}
			else
			{
				dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v1[i]] + value[i]);
			}
		}
	}
	cout << dp[num][v] << endl;
	return 0;
}

结果符合第一问的题目要求, 代码正确。

结束语

        到了这里我们今天的内容就全部结束了,希望今天的内容能够给大家带来些帮助,最后在这里感谢大家的支持啦! 

评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小张﹉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值