这是一篇菜鸟的笔记~
问题描述
在猫星球上,小R负责给一行排队的猫分发鱼干。每只猫有一个等级,等级越高的猫应该得到更多的鱼干。规则如下:
- 每只猫至少得到一斤鱼干。
- 如果一只猫的等级高于它相邻的猫,它就应该得到比相邻的猫更多的鱼干。
小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博客)
贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。
主要步骤:
- 问题分解:将问题分解为一系列子问题。
- 局部最优选择:在每个子问题中,选择当前看起来最优的解决方案。
- 合并子问题的解:将所有子问题的解合并,得到原问题的解。
求解过程
针对这个问题,我们需要逐步计算并满足局部最优条件(即相邻猫的等级差异)来达到全局最优(即最少鱼干数量)。根据贪心策略,我们每次只考虑当前猫与相邻猫的关系,而不用考虑全局所有猫的关系。
在每次给猫分配鱼干时,都要遵循“等级越高,鱼干越多”的原则,并且还要保证相邻猫之间的鱼干数量差异。因此,采用两次遍历:一次从左到右,确保每只猫比它左边的猫得到更多的鱼干(等级更高的前提下);另一次从右到左,确保每只猫比它右边的猫也得到更多的鱼干(等级更高的前提下)。
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数组中所有元素的和,即为所需的最少鱼干数量。
总结
此外,也许可以考虑在第一次遍历时就同时考虑左边和右边的猫,以减少遍历次数,不过可能需要额外的数组来存储信息。