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

50 阅读3分钟

这是一篇菜鸟的笔记~

问题描述

在猫星球上,小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

解析

使用一个数组 fish_amounts 来记录每只猫分配到的鱼干数量,同时使用贪心算法进行解答。

贪心算法

参考(贪心算法(greedy algorithm,又称贪婪算法)详解(附例题)-CSDN博客)

贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。

主要步骤:

  1. 问题分解:将问题分解为一系列子问题。
  2. 局部最优选择:在每个子问题中,选择当前看起来最优的解决方案。
  3. 合并子问题的解:将所有子问题的解合并,得到原问题的解。

求解过程

针对这个问题,我们需要逐步计算并满足局部最优条件(即相邻猫的等级差异)来达到全局最优(即最少鱼干数量)。根据贪心策略,我们每次只考虑当前猫与相邻猫的关系,而不用考虑全局所有猫的关系。

在每次给猫分配鱼干时,都要遵循“等级越高,鱼干越多”的原则,并且还要保证相邻猫之间的鱼干数量差异。因此,采用两次遍历:一次从左到右,确保每只猫比它左边的猫得到更多的鱼干(等级更高的前提下);另一次从右到左,确保每只猫比它右边的猫也得到更多的鱼干(等级更高的前提下)。

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
        # 如果等级相同或更低,保持为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)

首先将数组fish_amounts初始化为[1, 1, ..., 1],即表示每一只猫最少都可以获得一条鱼干。

然后从左到右遍历输入的等级数组,从第二只猫开始,比较当前猫和前一只猫的等级。如果当前猫的等级高于前一只猫,则当前猫的鱼干数量应比前一只猫多1;如果当前猫的等级等于或低于前一只猫,则当前猫的鱼干数量保持为1。

再者,从右到左遍历,从倒数第二只猫开始,比较当前猫和后一只猫的等级,防止遗漏。如果当前猫的等级高于后一只猫,则当前猫的鱼干数量应比后一只猫多1;如果当前猫的等级等于或低于后一只猫,则当前猫的鱼干数量保持为1。

最后,计算fish_amounts数组中所有元素的和,即为所需的最少鱼干数量。

总结

此外,也许可以考虑在第一次遍历时就同时考虑左边和右边的猫,以减少遍历次数,不过可能需要额外的数组来存储信息。