java动态规划装箱问题_【简单动态规划】装箱问题(Python实现)

【简单动态规划】装箱问题(Python实现)

题目描述:

有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。

要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

输入描述:

1.一个整数v,表示箱子的容量

2.一个整数n,表示有n个物品

3.接下来n个整数,分别表示这n 个物品的各自体积

输出描述:

一个整数,表示箱子剩余空间。

样例输入:

10

3

5

8

4

样例输出:

1

递归解法

假设rec_opt(v,n)这个函数能得到答案,其中v表示箱子的容量、n表示前n个物品。那么rec_opt(v,n) 就表示选前n个物品中放入容量为v的箱子中,最后得到箱子剩余空间的最小值。

以样例来做示范,要求rec_opt(10,3)就要考虑第3个物品放不放入箱子:

①选择第3个物品放入箱子,则此时箱子的空间还剩下6,且接下来只需考虑前2个物品即求rec_opt(6,2)。

②不选择第3个物品放入箱子,则此时箱子的空间剩下10,且接下来同样只需考虑前2个物品即求rec_opt(10,2)。

③比较rec_opt(6,2)和rec_opt(10,2)的大小,选择较小的。

继续按照以上的思路递推rec_opt(6,2)和rec_opt(10,2)。

接下来考虑返回的情况:

①当n=0时,即没有物品可选,此时只需返回剩余的空间v即可。

②当v=0时,即没有空间再装物品了,此时只需返回剩余空间v=0即可。

③当v

选第3个物品(体积4)不选第3个物品(体积4)不选第2个物品(体积8)选第2个物品(体积8)选第2个物品(体积8)不选第2个物品(体积8)选第1个物品(体积5)不选第1个物品(体积5)选第1个物品(体积5)不选第1个物品(体积5)选第1个物品(体积5)不选第1个物品(体积5)rec_opt(10,3)rec_opt(6,2)rec_opt(10,2)rec_opt(6,1)剩余空间不足rec_opt(2,1)rec_opt(10,1)返回rec_opt(1,0)=1返回rec_opt(6,0)=6剩余空间不足返回rec_opt(2,0)=2返回rec_opt(5,0)=5返回rec_opt(10,0)=10

用Python3来实现:

v = int(input())

n = int(input())

w = [0]*n

for i in range(0,n):

w[i] = int(input())

def rec_opt(v,n):

if n==0:

return v

elif v==0:

return 0

elif v

return rec_opt(v,n-1)

else:

A = rec_opt(v-w[n-1],n-1)#选第n件物品

B = rec_opt(v,n-1)#不选第n件物品

return min(A,B)

print(rec_opt(v,n))

运行结果:

4ae2df0a82e6c9acc4d90be1a7ff143f.png

动态规划解法

动态规划实际上就是将子问题的结果保存起来,下次需要时直接访问即可不用再像递归那样再次计算,通常都会把保存子问题结果的数组命名为dp。

创建一个dp[n+1][v+1]数组,表示前n个物品装入容量为v的箱子中的最大容量。最后用容量v减去装入的最大容量即得剩余最小容量。

注:笔者这里的动态规划有点复杂,其他博主的解法用的是一维数组简单易懂。这里仅对笔者的结果进行展示,不做过多的解释。

样例的dp数组的内容:

物品\容量

0

1

2

3

4

5

6

7

8

9

10

0

0

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

0

5

5

5

5

5

5

2

0

0

0

0

0

5

5

5

8

8

8

3

0

0

0

0

4

5

5

5

8

9

9

用Python3实现:

v = int(input())

n = int(input())

w = [0]*n

for i in range(0,n):

w[i] = int(input())

def dp_opt(v,n):

dp = [[0]*(v+1) for _ in range(n+1)]

for i in range(1,n+1):

for j in range(1,v+1):

if w[i-1]<=j:

for k in range(0,i):

dp[i][j] = max(max(dp[k][j-w[i-1]]+w[i-1],dp[i][j]),dp[i-1][j])

else:

dp[i][j] = dp[i-1][j]

return dp[n][v]

print(v-dp_opt(v,n))

运行结果:

521cbf03abb32199fa73cc037e8ff956.png

注:此问题的分析过程参考、学习了B站up主(正月点灯笼)的视频。

特别声明:笔者不是计算机专业,肯定会有不少的问题,欢迎批评指正!!!

点赞

收藏

分享

文章举报

b9f117493e7fdbd9a5abef55967294f0

d1358d4695d8660de2972cc1f6e682b2.png

W&Z

发布了2 篇原创文章 · 获赞 0 · 访问量 176

私信

关注

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值