最近看到了一个有趣的小问题,整理了一些自己的思考,对此做一个简单的总结。
问题如下:
我在某宝买了100袋乐事大波浪薯片,薯片到了菜鸟驿站,菜鸟驿站距离我家500米,我要把薯片全部拿回家。但是,我每次最多只能拿50袋,并且我嘴馋,只要手上有薯片,每走10米就要吃掉一袋。请问,我最多能把几袋薯片拿回家?
假设:
1.我中途可以把薯片放在地上,不会被人拿走
2.我可以一次取一部分的快递
3.在对问题的理解中,可以认为走路与吃薯片是同时发生的,我一边走路一边吃薯片。这个过程是连续的(比方说我走了3.3333米吃了三分之一包薯片)。但是,为简化模型,在实际建模过程中可以考虑离散情况,即:我每次至少走10米,一包薯片必须吃完。我从出发点开始,每走十米吃掉一包薯片。
4.我只能一个人搬薯片,不能借助其余外力
5.我作为一个人不会累,在手上没有薯片时可以不停来回而没有损耗
思路:
最后剩下的薯片最多>吃掉的薯片最少>带着薯片走的路程最少>每次带最多的薯片走
策略:
1.每次携带能携带的最多的薯片前进一个单位(10米)
2.如果除了手中的薯片还有其余薯片在后面,则回头补充薯片,每次补充能携带的最多的薯片
3.如果除了手中薯片,没有其余薯片,则一直前进
我们可以将这个策略用python代码实现
def method(x, u, l, m):
x0 = 0
l0 = m
l1 = 0
c = 0
while True:
# 如果第一步时能搬的东西大于负重,则按最大负重搬运前进一步,之后补充物资
if l1 == 0 and l0 >= l:
l1 = l0 - l
l0 = l - 1
x0 = x0 + u
c = c + 1
else:
# 如果发现剩下的物资大于最大负重,再次按最大负重搬运物资
if l1 >= l:
l0 = l0 + l - 1
l1 = l1 - l
c = c + 1
else:
if 0 < l1 < l:
# 如果剩下物资不足最大负重,则全部搬过来
l0 = l0 + l1 - 1
l1 = 0
c = c + 1
else:
# 如果没有剩余,则一直往前走
x0 = x0 + u
l0 = l0 - 1
c = c + 1
if x0 == x and l1 == 0 :
break
return c, l0
def myanswear():
x = int(input('路程'))
u = int(input('每单位消耗所走里程'))
l = int(input('最大负重'))
m = int(input('总量'))
a, b = method(x, u, l, m)
print('路途中的损耗是:')
print(a)
print('最终剩下:')
print(b)
myanswear()
显而易见,上述代码针对离散的情形(取整数的路程、最大负载、总货物量、消耗等均取整数)具有一定的泛化能力。
按照题意,输入参数 x=500,u=10,l=50,m=100,即可得到结果。
这个策略下,最终最小损失为75 ,能带回家25包薯片。
经过分析可以发现,在题目给定参数条件下,最优化算法结果与方法2相同。
方法2:
先搬50袋薯片到半路停下(手中剩25袋薯片)
回头再搬50袋薯片到半路
一次搬50袋薯片到终点