【简单动态规划】装箱问题(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))
运行结果:
动态规划解法
动态规划实际上就是将子问题的结果保存起来,下次需要时直接访问即可不用再像递归那样再次计算,通常都会把保存子问题结果的数组命名为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))
运行结果:
注:此问题的分析过程参考、学习了B站up主(正月点灯笼)的视频。
特别声明:笔者不是计算机专业,肯定会有不少的问题,欢迎批评指正!!!
点赞
收藏
分享
文章举报
W&Z
发布了2 篇原创文章 · 获赞 0 · 访问量 176
私信
关注