豆包MarsCode AI 刷题——传送带包裹输送问题| 豆包MarsCode AI刷题

162 阅读4分钟

image.png

问题思路

题目要求我们在限定的天数内,通过合理分配每天的运输量,确保所有包裹都能被运送到目的地。这个问题可以转化为一个典型的背包问题,其中我们需要在给定的天数(背包容量)内,运输尽可能多的包裹(物品),同时不超过每天的运输能力(背包容量限制)。

我们可以采用二分查找来解决此问题。因为运载能力的取值范围是有边界的,下限是weights中的最大值(若运载能力小于此值,最大的包裹无法运输),上限是weights的总和(若运载能力等于总和,可一天运完所有包裹)。在二分查找过程中,对于每次尝试的运载能力mid,计算按此运载能力运输所有包裹需要的天数cur_days。若cur_days小于等于days,说明运载能力可能过大,应缩小上限;若cur_days大于days,说明运载能力过小,应增大下限。

问题详解

这是一个典型的二分查找问题,我们需要找到一个最小的运载能力值,使得在这个能力下,所有包裹能在限定的天数内被运送。

首先确定二分查找的上下界:上界是所有包裹重量之和(即总重量),下界是包裹中的最大单个重量。

接着编写辅助函数:创建一个函数can_ship_in_days(capacity)来判断在给定的运载能力下,是否可以在规定的天数内完成运输。

最后二分查找逻辑:通过不断调整中间值mid,根据can_ship_in_days(mid)的返回结果来调整上下界,直到找到最小的运载能力。

代码

def solution(weights: list, days: int) -> int:

    # 辅助函数:检查给定的运载能力是否能在 days 天内完成运输

    def can_ship_in_days(capacity: int) -> bool:

        # 初始化当前天数和当前载重

        current_days = 1

        current_load = 0    

        for weight in weights:

            # 如果当前载重加上当前包裹的重量超过 capacity,则需要新的一天

            if current_load + weight > capacity:

                current_days += 1

                current_load = weight

            else:

                current_load += weight

        # 返回是否能在 days 天内完成运输

        return current_days <= days

    # 二分查找的左右边界

    left, right = max(weights), sum(weights)

    # 二分查找

    while left < right:

        mid = (left + right) // 2

        if can_ship_in_days(mid):

            right = mid

        else:

            left = mid + 1

    return left

 

if name == 'main':

    print(solution(weights=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1], days=5) == 15)

    print(solution(weights=[3, 2, 2, 5, 1, 4], days=2) == 10)

    print(solution(weights=[1, 2, 3, 8, 4], days=4) == 8)

代码详解

1.函数定义与辅助函数

def solution(weights: list, days: int) -> int:定义了主函数,接受包裹重量列表和天数作为参数,并返回最低运载能力。

def can_ship_in_days(capacity: int) -> bool:是辅助函数,用于检查给定的运载能力是否能在days天内完成运输。在这个函数中:

初始化current_days = 1和current_load = 0,分别表示当前天数和当前载重。

遍历weights列表,对于每个包裹重量weight,如果current_load + weight > capacity,则需要新的一天,current_days加 1,current_load重置为weight;否则,current_load加上weight。

最后返回current_days <= days,判断是否能在规定天数内完成运输。

2.二分查找实现

left, right = max(weights), sum(weights)初始化了二分查找的左右边界。

在while left < right:循环中:

mid = (left + right) // 2计算中间运载能力。

通过if can_ship_in_days(mid):判断以mid为运载能力是否能在days天内完成运输。若可以,right = mid缩小上限;否则,left = mid + 1增大下限。

最后返回left,即最低运载能力。

3.主程序测试

在if name == 'main':部分,对solution函数进行了测试,分别传入了题目中给出的三组测试数据,验证函数返回值是否正确。

知识总结

在使用豆包MarsCode AI刷题过程中,我学到了以下几个新知识点:

二分查找的应用场景:二分查找不仅仅适用于有序数组的查找,还可以用来解决很多优化类问题,比如寻找最优解或者阈值等问题。

辅助函数的重要性:在处理复杂的逻辑时,引入辅助函数不仅可以使主函数更加简洁易懂,还能方便地复用这些逻辑。

边界条件的处理:在编写算法时,一定要注意边界条件的处理,避免出现错误的结果。

多做练习:只有通过大量的实践才能真正掌握一门技术。

学会总结:每次做完一道题之后,都要花时间去回顾和总结,看看有没有什么可以改进的地方。

利用好工具:像豆包MarsCode这样的工具可以帮助我们更好地管理学习进度,提升效率。 

工具运用

豆包MarsCode AI刷题功能提供了丰富的题目资源和智能化的指导,可以帮助用户更高效地学习。结合其他学习资源,如在线教程、视频讲解等,可以进一步丰富学习体验,提高学习效果。