mysql 游戏背包_01背包问题(完全背包,部分背包)golang实现

这篇博客介绍了如何使用Golang实现经典的动态规划问题——背包问题,包括01背包、完全背包和部分背包。通过示例和代码解析,阐述了如何在不同背包约束下最大化物品价值,并总结了解题思路。
摘要由CSDN通过智能技术生成

很经典的动态规划问题,具体思路这里就不列出了,网上太多资料了。想要详细理解的话可以去看背包九讲

这里分别列出,01背包,完全背包,部分背包 golang实现。

01背包

给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi 。

应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?

从左往右,从上往下填表(example: 5表示重量,12表示价值)

f0e22a711c48f71e029bc329f940fe72.png

1.png

代码and注释

dp[i][j] = max(dp[i-1][j], nums[i][1]+dp[i-1][j-nums[i][0]]) 仔细想清楚这一行

ef7fdfd70654478bda07933c72f92773.png

backpack.png

完全背包

给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi,每个物品都有无限多件,现在往背包里面装东西,怎么装能使背包的内物品价值最大?

先看图:

这是一个一维数组,每一行表示每次遍历的结果

11c57e47cdea3f0117bae1b1c593607f.png

2.png

代码and注释,理解上面一个,这个也很好理解

de5ed82f43e0ca9c7926827190f1878e.png

backpack1.png

部分背包

给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi,每个物品都有ki件,现在往背包里面装东西,怎么装能使背包的内物品价值最大?

一个比较简单但是效率不高的方法: 把物品i的ki件物品转化为k件不同的物品,直接就转化为01背包问题了。不过效率较低。

另一种思路:再申请一个数组来保存物品i的使用个数,从而控制物品i的数量,用完全背包的思路解决问题

代码and注释

9b6a6bd890c550c47b160b21798a9fdf.png

backpack3.png

遍历过程:dp表示每遍历一个物品时的最优价值,count表示重量为n时放入物品i的个数

dp[0 0 0 0 0 8 8 8 8 8 16 16 16 16 16 16]

count[0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 2]

dp[0 0 0 0 3 8 8 8 8 11 16 16 16 16 19 19]

count[0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1]

dp[0 0 0 0 3 8 8 10 10 11 16 16 18 18 20 20]

count[0 0 0 0 0 0 0 1 1 0 0 0 1 1 2 2]

dp[0 0 3 3 6 8 9 11 11 14 16 17 19 19 22 22]

count[0 0 1 1 2 0 3 1 1 2 0 3 1 1 2 2]

dp[0 0 3 3 6 8 9 11 11 14 16 17 19 19 22 22]

count[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

总结:

基本上背包问题的解题思路最终都会转化为01背包问题,核心代码都是基于一个公式:

f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}

代码还有很大优化空间。只是记录一下自己的学习过程。

有疑问加站长微信联系(非本文作者)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值