问题描述
在猫星球上,小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来记录每只猫得到的鱼干的数量。因为每只猫至少得到一斤鱼干,所以将其初始化为1,即fish[i]=1。
题目要求如果猫的等级比邻居高,那么这只猫分得的鱼干也要比邻居多。也就是说,如果某只猫的等级比左边邻居的等级高,它必须比左边的猫分到更多的鱼干。如果某只猫的等级比右边邻居的等级高,它也必须比右边的猫分到更多的鱼干。我们可以把左右的比较拆开来,先从左往右遍历和左边的比较一次,如果当前这只猫的等级比它左边的猫高,那么当前这只猫的鱼干就要比左边那只猫多一斤。如果等级和左边的猫相等或者比左边的猫小,那么就不做处理,依然是一斤。然后再返过来和右边的比较一次,再从右往左遍历和右边的比较一次,如果当前这只猫的等级比它右边的猫高。那么当前这只猫的鱼干至少要比右边那只猫多一斤,但是需要取当前这只猫已经有的鱼干数量和比右边那只猫的鱼干多一斤这两个数量中的最大值,以满足题目要求。最后再统计每只猫分得的鱼干数量,加起来就是题目的答案了。
代码实现
int solution(int n, vector<int> catsLevels) {
// Please write your code here
vector<int> fish (n,1);
for (int i = 1;i < n; i++)
{
if (catsLevels[i]>catsLevels[i-1])
{
fish[i] = fish[i-1]+1;
}
}
for (int i = n-2; i >= 0; --i)
{
if (catsLevels[i]>catsLevels[i+1])
{
fish[i] = max(fish[i],fish[i+1]+1);
}
}
int totleFish = 0;
for (int num:fish)
{
totleFish += num;
}
return totleFish;
}
算法总结
- 贪心算法:该算法采用了贪心策略,即在每一步选择当前看起来最优的选择,即在每一边的比较中,都确保当前猫的鱼干数量至少比等级低的邻居多一斤。
- 两次遍历:算法需要两次遍历数组,一次从前向后,一次从后向前,以确保所有等级差异都被考虑到。
- 动态规划思想:虽然这个算法不是传统意义上的动态规划算法,但它使用了类似于动态规划的思想,即基于之前计算的结果来更新当前的状态。