在01背包问题中,dp算法做了什么

昨天,我更新win11,关于win11和win10的差异,我做了一篇文章,感兴趣的朋友可以过去看一下。关于更新了Win11的一些看法_aizim的博客-CSDN博客就在昨天的时候,我的电脑更新了Windows11的系统,在此次更新中,刚开始我觉得不太适应,但是使用了半天,开始发表一下关于更新Win11的看法。与Windows10的差异界面差异任务栏在此次更新之后,win11的画面相对比win10来说,可以用两个字来形容,就算简洁和有序,首先最明显的差别就算底部的任务栏从原本祖传下来的靠左展示变成了中部的的转变如果不习惯的小伙伴也可以从设置的个性化中更改回来我实际上对于这个改变是比较新颖的,优点是符合人体视觉的中心化,但是缺点也是有的,比如我https://blog.csdn.net/aizim/article/details/121108444

进入正题,本篇文章给大家展示一下如何理解dp算法的真正含义以及给大家启发以后该如何使用。

从变量到创建函数到最后实现代码,一步一步刨析dp算法。

变量

const int MAX = 1000;
int f[MAX][MAX];
int v[MAX],w[MAX];
int n, k;

第一行的const定义常量,第二行v[]w[]表示物品的体积和价值,第三行的f[][]表示函数f(n,k),第四行n表示定义物品的数量,k表示背包所能容纳的最大体积。

f(n,k)所代表的是一个函数,若n为4,k为5。

四个物品的体积为:1  2  3   4      价值为:2  4  4  5。

那么f(4,5)的值为8,这个值是如何得来的?通过推到的方式找出8的值,我们可以从四号物品开始推导若选择了四号物品,那么仔细对比一下发现,无法选择出最大值,在此次推导的过程中,我们把选择四号物品和不选择四号物品进行了一次比较

如果不选择四号物品,那么就选择三号物品,选择了三号物品发现有两个结果,第一个是和二号物品组成价值结果8,第二个是和一号物品组成价值结果6,这个过程,是选择三号物品当中,再与第一个物品或第二个物品进行了比较

上述可以发现,我们其实并不是像数学一样求函数,而是创建一个变量,一次一次的比较,找出最大的值。

函数f(n,v)的作用

 以上是整个过程的推导图,若计算机按照此推导图进行,即可出现答案。

但是很多同学就卡在这个地方,如何将这个推导的过程通过代码实现?本人刚开始看到这个推导图的时候也是一头雾水,实际上,这样给出的思路是人性化的,具有跳跃性

但是仔细思考了一会,这个推导过程不能从上面讲的方式开始一步一步实现代码,而是从最底层反推到最高层f(4,5)是通过比较下面的f(3,1)+5f(3,5)但是这些数据是空的,做到下一层的时候就卡死了。所以应该从最底层开始对比大小,比完最底层的大小之后,就有数据支撑下一层的的对比大小,这样才是正确编程思路

实现代码

如果确认了角度,f(n,v)的值就是比较f(n-1,[0~k])和f(n-1,[0~k]-v[n-1])+w[n-1](n-1号物品的价值)进行比较,有了第一层的数据作为支撑。代码为

f[n][k] = max(f[n-1][k],f[n-1][k-v[n-1]]+w[n-1]);

而如果剩余的体积没办法容纳此物品,则需要在下一层的结果进行覆盖代码为

f[n+1][k] = f[n][k];

判断条件为:

if(k<v[i])

而从第一步开始推导的的是f[1][k]=max(f[0][k],f[0][k-v[0]]+w[0]),下一步就是算出f[2][k],f[3][k].....

所以需要循环语句,f[n][k]n从0开始递增到最顶层,而k也要创建一个循环,以此找出所有的剩余背包容量的结果,比较最大值。

当两个循环都进行完毕以后,输出f[n][k]就算顶层的最终答案。

原代码

int dp()
{

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j <= k; j++)
		{
			if (j < v[i])f[i + 1][j] = f[i][j];
			else f[i + 1][j] = max(f[i][j], f[i][j - v[i]] + w[i]);
		}
	}
	return 0;
}

感谢大家收看,如果喜欢的话,请点赞支持一下,我还会持续更新此系列,不仅自己学习,也方便记录自己的思路,和大家一起讨论

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值