题目分析:贪心猫的鱼干大分配 | 豆包MarsCode AI刷题

97 阅读5分钟

题目

贪心猫的鱼干大分配

问题描述

在猫星球上,小R负责给一行排队的猫分发鱼干。每只猫有一个等级,等级越高的猫应该得到更多的鱼干。规则如下:

  1. 每只猫至少得到一斤鱼干。
  2. 如果一只猫的等级高于它相邻的猫,它就应该得到比相邻的猫更多的鱼干。

小R想知道,为了公平地满足所有猫的等级差异,他至少需要准备多少斤鱼干。

测试样例

样例1:

输入:n = 3, cats_levels = [1, 2, 2]
输出:4

样例2:

输入:n = 6, cats_levels = [6, 5, 4, 3, 2, 16]
输出:17

样例3:

输入:n = 20, cats_levels = [1, 2, 2, 3, 3, 20, 1, 2, 3, 3, 2, 1, 5, 6, 6, 5, 5, 7, 7, 4]
输出:35


分析

首先,我们需要给每只猫分配鱼干,满足以下条件:

  1. 每只猫至少得到一斤鱼干。
  2. 如果一只猫的等级高于它相邻的猫,它应该得到比相邻的猫更多的鱼干。

所以我们可以使用一个数组 fish_amounts 来记录每只猫分配到的鱼干数量。初始时,每只猫至少得到一斤鱼干,即 fish_amounts 初始化为 [1] * n

那么算法步骤则为:

  1. 初始化:创建一个长度为 n 的数组 fish_amounts,初始值为 1fish_amounts = [1] * n 初始化每只猫至少得到一斤鱼干。

  2. 从左到右遍历:确保每只猫的鱼干数量满足条件:

    • 如果当前猫的等级高于前一只猫,则当前猫的鱼干数量应比前一只猫多 1for i in range(1, n) 确保每只猫的鱼干数量满足条件。
    • 如果当前猫的等级等于或低于前一只猫,则当前猫的鱼干数量保持为 1for i in range(n - 2, -1, -1) 再次确保每只猫的鱼干数量满足条件。
  3. 从右到左遍历:由于我们只从左到右遍历了一次,可能存在某些猫的鱼干数量不满足条件。因此,我们需要再次从右到左遍历,确保每只猫的鱼干数量满足条件。

  4. 计算总鱼干数量:最后,计算 fish_amounts 数组中所有元素的和,即为所需的最少鱼干数量。return sum(fish_amounts) 返回总鱼干数量。


所涉及的知识点

  1. 数组操作

    • 初始化数组:fish_amounts = [1] * n
    • 遍历数组:for i in range(1, n) 和 for i in range(n - 2, -1, -1)
    • 数组元素的比较和更新:if cats_levels[i] > cats_levels[i - 1] 和 fish_amounts[i] = fish_amounts[i - 1] + 1
  2. 贪心算法

    • 通过两次遍历(从左到右和从右到左)来确保每只猫的鱼干数量满足条件。
    • 贪心算法的核心思想是每次选择局部最优解,最终得到全局最优解。
  3. 条件判断

    • 使用 if 语句来判断当前猫的等级是否高于相邻的猫。
    • 使用 max 函数来确保鱼干数量满足条件:fish_amounts[i] = max(fish_amounts[i], fish_amounts[i + 1] + 1)
  4. 求和操作

    • 使用 sum 函数计算数组中所有元素的和:return sum(fish_amounts)

通法总结

  1. 问题理解

    • 仔细阅读题目描述,理解题目要求和约束条件。
    • 明确题目中的关键点和需要解决的核心问题。
  2. 数据结构选择

    • 根据题目要求选择合适的数据结构。常见的数据结构包括数组、列表、栈、队列、哈希表等。
    • 初始化数据结构,确保满足题目中的初始条件。
  3. 算法设计

    • 遍历:通常需要对数据结构进行遍历,以处理每个元素。常见的遍历方式包括从左到右、从右到左、双指针等。
    • 条件判断:在遍历过程中,根据题目要求进行条件判断,更新数据结构中的元素。
    • 贪心算法:如果题目要求局部最优解,可以考虑使用贪心算法。贪心算法的核心思想是每次选择局部最优解,最终得到全局最优解。
    • 动态规划:如果题目涉及最优子结构和重叠子问题,可以考虑使用动态规划。动态规划通常需要定义状态和状态转移方程。
  4. 结果计算

    • 根据题目要求,计算最终结果。常见的计算方式包括求和、求最大值、求最小值等。

本题题解

def solution(n, cats_levels):
    # 初始化每只猫至少得到一斤鱼干
    fish_amounts = [1] * n
    
    # 从左到右遍历,确保每只猫的鱼干数量满足条件
    for i in range(1, n):
        if cats_levels[i] > cats_levels[i - 1]:
            fish_amounts[i] = fish_amounts[i - 1] + 1
    
    # 从右到左遍历,确保每只猫的鱼干数量满足条件
    for i in range(n - 2, -1, -1):
        if cats_levels[i] > cats_levels[i + 1]:
            fish_amounts[i] = max(fish_amounts[i], fish_amounts[i + 1] + 1)
    
    # 计算总鱼干数量
    return sum(fish_amounts)

if __name__ == "__main__":
    #  You can add more test cases here
    cats_levels1 = [1, 2, 2]
    cats_levels2 = [6, 5, 4, 3, 2, 16]
    cats_levels3 = [1, 2, 2, 3, 3, 20, 1, 2, 3, 3, 2, 1, 5, 6, 6, 5, 5, 7, 7, 4]
    print(solution(3, cats_levels1) == 4)
    print(solution(6, cats_levels2) == 17)
    print(solution(20, cats_levels3) == 35)