1.题目
问题描述
假如有一群猫排成一行,要分配鱼干,每一只猫都有一个等级值。你作为管理员有很多鱼干但是需要按下边的分配制度分配:
- 每一只猫至少要分配一斤鱼干,鱼干分配最小单位是斤,必须保证是整数。
- 猫比他们邻居有更高等级值的分配的鱼干要多于他们的邻居。
为了满足上边的分配规则,需要得到需要的最少鱼干数量。
输入格式
第 1 行输入猫的数量 N
从第 2 行到第 N + 1 行,输入每一只猫的等级值 D。
输出格式
输出一个整数,表示需要的鱼干数量(斤)
输入样例
3
1
2
2
输出样例
4
数据范围
1 <= N <= 10^3
1 <= D <= 10^6
2.思路
两次遍历的贪心算法(从左到右、从右到左)
注意:
在 右向左 遍历时,应该确保 fish[i-1] 至少比 fish[i] 大 1,但不能覆盖之前的 fish[i-1] 值。
有可能fish[i - 1]前面已经加的很大,fish[i] + 1有可能会覆盖之前的 fish[i-1] 值,使fish[i - 1]变小,不符合要求。因此,需要用 max(fish[i-1], fish[i] + 1) 以保证不会错误减少已分配的鱼干数量。
3.代码
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
int solution(int n, std::vector<int> cats_levels) {
// Please write your code here
vector<int> fish(n, 1); // 初始化每个小猫分一个鱼干
// 从左往右遍历
for (int i = 0; i < n - 1; i++) {
if (cats_levels[i] < cats_levels[i + 1]) {
fish[i + 1] = fish[i] + 1; // 比前一只猫多一个鱼干
}
}
// 从右往左遍历
for (int i = n - 1; i > 0; i--) {
if (cats_levels[i] < cats_levels[i - 1]) {
fish[i - 1] = max(fish[i - 1], fish[i] + 1);
}
}
return accumulate(fish.begin(), fish.end(), 0); //0是初始的累加值
}
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;
std::cout << (solution(20, catsLevels3)) << std::endl;
return 0;
}