56.贪心猫的鱼干大分配
问题描述
在猫星球上,小R负责给一行排队的猫分发鱼干。每只猫有一个等级,等级越高的猫应该得到更多的鱼干。规则如下:
- 每只猫至少得到一斤鱼干。
- 如果一只猫的等级高于它相邻的猫,它就应该得到比相邻的猫更多的鱼干。
小R想知道,为了公平地满足所有猫的等级差异,他至少需要准备多少斤鱼干。
1.思路
1.动态规划算法选择
递推i号猫分到的鱼干数量,保证每只猫分到最少鱼干数量,就能求出最少准备的鱼干数
##### 2.集合选择dp[i]表示第i号猫分到的的鱼干数量。
##### 3.从左向右从左向右,先保证右边等级高的猫分到的鱼干永远比左边等级低的猫分到的鱼干多1
##### 4.集合划分在保证右边高级猫分到鱼干数多于左边低级猫后,集合可以划分为高级猫不比右边高、高级猫本身就比右边高,也就是dp[i+1]+1(要比右边高,因此值加1),dp[i]
##### 5.计算结果求最少准备鱼干数,遍历数组计算总鱼干数
2.注意事项
1.初始化
题目要求每只猫至少得到一斤鱼干,因此数组初始化为1
2.边界问题
从左向右保证右边等级高的猫分到的鱼干永远比左边等级低的猫分到的鱼干多时,用i和i-1做判断避免溢出 从右向左递推求i号猫分到的鱼干数量时,i从n-2开始,做i和i+1判断避免溢出
3.复杂度
时间复杂度:递推计算,时间复杂度为O(n) 空间复杂度:n大小数组,空间复杂度为O(n)
代码实现
#include <bits/stdc++.h>
using namespace std;
int solution(int n, std::vector<int> catsLevels) {
// Please write your code here
vector<int> dp(n, 1);
int sum = 0;
for (int i = 1; i < n; i++) {//从左向右,保证等级高的猫鱼干多于左侧
if (catsLevels[i] > catsLevels[i - 1]) {
dp[i] = dp[i - 1] + 1;
}
}
for (int i = n - 2; i >= 0; i--) {//从右向左,保证等级高的猫鱼干多于右侧
if (catsLevels[i] > catsLevels[i + 1]) {
dp[i] = max(dp[i], dp[i + 1] + 1);
}
}
for (int i = 0; i < n; i++) {
sum += dp[i];
}
return sum;
}
int main() {
std::vector<int> catsLevels1 = {1, 2, 2};
std::vector<int> catsLevels2 = {6, 5, 4, 3, 2, 16};
std::vector<int> catsLevels3 = {1, 2, 2, 3, 3, 20, 1, 2, 3, 3,
2, 1, 5, 6, 6, 5, 5, 7, 7, 4};
std::cout << (solution(3, catsLevels1) == 4) << std::endl;
std::cout << (solution(6, catsLevels2) == 17) << std::endl;
std::cout << (solution(20, catsLevels3) == 35) << std::endl;
return 0;
}