贪心猫的鱼干分配| 豆包MarsCode AI刷题

43 阅读5分钟

题目解析

题目背景:在银河星球上,小欣负责给一排排队的猫分发鱼干。每只猫有一个等级,等级越高的猫应该得到更多的鱼干。为了满足公平,规定如下:

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

问题:为了满足所有猫的公平需求,至少需要准备多少片鱼干?

输入输出示例

  • 输入:猫的数量 n 和一个等级列表 cats_levels
  • 输出:分配的最少鱼干总数。

例如:

示例 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. 初始化:每只猫至少得到 1 片鱼干。
  2. 从左到右遍历:确保从左到右,如果某只猫的等级比前一只猫高,则它得到的鱼干比前一只猫多。
  3. 从右到左遍历:确保从右到左,如果某只猫的等级比后一只猫高,则它得到的鱼干也要比后一只猫多。
  4. 求和:最后将所有猫得到的鱼干数目求和,得到答案。

这种双向遍历的方式确保每只猫在两侧的要求都得到了满足,同时保证了鱼干数量的最小化。

为了更好地帮助理解题目和思路,我将给出一个可视化的图解,展示如何分配鱼干。

图示分析

假设我们使用示例 1 中的数据,等级列表为 [1, 2, 2]。我们要分配最少的鱼干以满足题目的要求。以下是如何一步步分配鱼干的可视化过程。

初始状态

首先,给每只猫分配至少 1 片鱼干:

等级:    1   2   2
鱼干:    1   1   1

每只猫先分到 1 片鱼干,这是最基本的要求。

从左到右遍历

从左到右遍历每只猫,如果当前猫的等级比前一只猫高,那么它应该得到更多的鱼干:

  1. 第二只猫等级为 2,大于第一只猫的等级 1,因此分配 1 + 1 = 2 片鱼干给第二只猫:

    等级:    1   2   2
    鱼干:    1   2   1
    
  2. 第三只猫等级与第二只猫相同(都是 2),所以不需要更改第三只猫的鱼干数量:

    等级:    1   2   2
    鱼干:    1   2   1
    

从右到左遍历

从右到左遍历猫,如果当前猫的等级比后面一只猫高,则要确保它有更多的鱼干:

  1. 第二只猫等级与第三只猫相同(都是 2),因此不需要修改鱼干数量:

    等级:    1   2   2
    鱼干:    1   2   1
    
  2. 第一只猫等级为 1,低于第二只猫(等级 2),不需要修改第一只猫的鱼干数量:

    等级:    1   2   2
    鱼干:    1   2   1
    

最终结果

计算每只猫得到的鱼干数量,总数为 1 + 2 + 1 = 4

等级:    1   2   2
鱼干:    1   2   1
总和:    4

视觉化的解释图

为了更好地理解,给出一个图表来表示分配过程:

  • 横轴表示猫的序号
  • 纵轴表示鱼干的数量
猫的序号   1   2   3
等级      1   2   2
鱼干数量  1   2   1

在横轴上是猫的编号,每只猫的等级在上方展示,每只猫得到的鱼干数量在下方展示。

通过从左到右、从右到左的两次遍历,确保鱼干的数量能够满足题目要求,最小化总数。

最终结果

最终,每只猫得到的鱼干总数为 1 + 2 + 1 = 4

代码实现

以下是 Python 实现的完整代码及其详细注释:

def solution(n, cats_levels):
    # 创建一个数组用于存储每只猫的鱼干数量,初始分配 1 片鱼干
    fish_sticks = [1] * n

    # 从左到右遍历,确保每只猫比左侧等级低的猫获得更多鱼干
    for i in range(1, n):
        if cats_levels[i] > cats_levels[i - 1]:
            fish_sticks[i] = fish_sticks[i - 1] + 1

    # 从右到左遍历,确保每只猫比右侧等级低的猫获得更多鱼干
    for i in range(n - 2, -1, -1):
        if cats_levels[i] > cats_levels[i + 1]:
            fish_sticks[i] = max(fish_sticks[i], fish_sticks[i + 1] + 1)

    # 返回鱼干总数
    return sum(fish_sticks)

if __name__ == "__main__":
    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

代码详解

  1. 初始化鱼干数量

    • fish_sticks = [1] * n:每只猫先得到 1 片鱼干。
  2. 从左到右遍历

    • for i in range(1, n):从第二只猫开始遍历。
    • 如果当前猫的等级高于前一只猫 (cats_levels[i] > cats_levels[i - 1]),则它应比前一只猫多 1 片鱼干 (fish_sticks[i] = fish_sticks[i - 1] + 1)。
  3. 从右到左遍历

    • for i in range(n - 2, -1, -1):从倒数第二只猫开始遍历。
    • 如果当前猫的等级高于后一只猫 (cats_levels[i] > cats_levels[i + 1]),则它应比后一只猫多 1 片鱼干,为了确保满足之前从左到右遍历的条件,我们需要取 max(fish_sticks[i], fish_sticks[i + 1] + 1)
  4. 计算鱼干总数

    • sum(fish_sticks) 计算每只猫最终得到的鱼干数量的总和。

总结

这道题通过两次遍历猫的等级列表,确保每只猫的鱼干数量既满足自身等级的要求,又符合与邻居的相对关系,从而在公平的前提下尽量减少分配的总鱼干数量。两次遍历分别从左到右和从右到左进行,以确保每个方向的相邻猫的等级要求都能得到满足。