算法学习 - 01背包问题(动态规划C++)

动态规划

我在上一篇博客里已经讲了一点动态规划了,传送门:算法学习 - 动态规划(DP问题)(C++)

这里说一下,遇到动态规划应该如何去想,才能找到解决办法。

最主要的其实是要找状态转移的方程,例如上一篇博客里面,找的就是当前两条生产线的第i个station的最短时间和上一时刻的时间关系。

minTime(station[1][i]) = minTime(station[1][i-1] + time[i], station[2][i-1] + time[i] + trans[i-1])

今天要讲的问题是01背包问题。

01背包

问题描述

01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为W1,W2……Wn,与之相对应的价值为P1,P2……Pn。

求解这个背包能装的最大价值。(物体不能分割)。

求解思路

这个其实比上一道题难在哪里了呢?
难在上一题装配线始终是两个,不会多,不会少。我们变化的量只有装配站的多少。

这个题目变化的量一个是物品的数量,还有一个是背包的空间。就是说装配线不会随着station的多少而变化,但是背包的空间会随着物品的装入而变化。

所以我们需要做的是判断当背包剩余的空间为j的时候,能否装入第i个物品,并且总价值增加。
即:

d[j] = max ( d[j], d[j-v[i]] + w[i]); //v[i]表示第i个物品的体积,w[i]表示第i个物品的价值。

其实我最开始看到上面这个状态转移的方程的时候,觉得这不是肯定的在空间j的时候放入物品,价值大于不放入物品的。毕竟只要放入就证明增加了价值啊。

其实不是这个样子的,因为只有在最开始都没有装入的时候,所有的都是0. 装入就一定价值增加。但是假如我们的物品如下:

物品1: 空间 2 价值 5
物品2: 空间 4 价值 3

当我们放入第一件物品的时候,假设背包空间是5,那么d[2…5]都是为 5. 因为d[0…1]空间不够所以为0。 当我们放入物品2的时候,d[5] = 5 > d[5 - 4] + 3 因为d[1] = 0;

发现了没有! 并不是放入就一定总价值增加!

所以我们遍历所有物品,从第一个物品开始,找当空间为j的时候,装入物品是否会增加价值!

代码实现

代码其实行数很少,不好看那些写了两个屏幕的,可能并没有更多的功能。

//
//  main.cpp
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值