小米食堂每年都会举办一次厨艺大赛,假设参赛的厨师一共有n位(n < 1000),比赛结束后没有公布评分,但是站在领奖台上的一排厨师中每位厨师都能看到与自己相邻的厨师(左或者右)里评分比自己低(看不到比自己分数高的人的分数)的评分。比赛结束之后要发奖金,以1K为单位,每位厨师至少会发1K的奖金,另外,如果一个厨师发现自己的奖金没有高于比自己评分低的厨师的奖金,就会不满意,作为比赛组织方,小米食堂至少需要发放多少奖金才能让所有厨师满意。
输入描述:每组数据为n+1个正整数单空格分割,其中第一个数为参赛厨师的人数,后面n个数为每位厨师的得分(0-100)
输出描述:输出至少需要多少K的奖金
输入例子1:10 60 76 66 76 85 55 61 71 84 62
输出例子1:20
算法这题和【leet-code】542. 01 矩阵这题的解法一模一样,而且这题还更简单些。思路还是有两种,BFS和两次动态规划。
动态规划由于某一个位置的厨师获得的奖金是和两遍都有关的,即要比左右相邻位置上的奖金更高。为此,从左往右遍历更新后,还要从右往左遍历更新。直接看代码,注释很清楚。
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { // 初始化变量 int N; scanf("%d", &N); // prize[i]对应第i位厨师的奖金,初始化为1;score[i]对应第i位厨师的评分 vector<int> prize(N, 1), score(N); for (int i = 0; i < N; i++) { scanf("%d", &score[i]); // 在输入评分的时候也开始从左往右的比较,如果当前位置的厨师比左边位置的厨师评分高,那么应该加1 if (i != 0 && score[i] > score[i-1]) { prize[i] = prize[i-1] + 1; } } // 从右往左开始比较,由于最后一位厨师只受左边厨师的影响,所以只需从倒数第二位厨师开始 for (int i = N - 2; i >= 0; i--) { /* 如果当前位置的厨师评分比右边厨师评分高,那么应该有个比较,为什么是比较,而不是像从左往右的时候,直接加1呢? 想象厨师评分如下: 1 2 3 4 2,那么倒数第二位厨师的奖金应该为max(4, 1+1) = 4,如果没有比较仅是加1那么倒数第二位厨师获得 的奖金为2了,那就错了。*/ if (score[i] > score[i+1]) prize[i] = max(prize[i], prize[i+1] + 1); } // 将所有厨师的应得奖金累加 int total = 0; for (int i = 0; i < N; i++) total += prize[i]; printf("%d\n", total); return 0; } BFS这题我没用BFS做,但我觉得大致的思路应该是再输入所有的评分后,然后遍历令比相邻位置评分都低的位置入队。然后从队列弹出位置比较评分情况然后更新左右两端,若有更新,将更新的位置入队,重复上述操作直到队列为空。