題目描述
小米食堂每年都會舉辦一次廚藝大賽,假設參賽的廚師一共有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做,但我覺得大致的思路應該是再輸入所有的評分後,然後遍歷令比相鄰位置評分都低的位置入隊。然後從隊列彈出位置比較評分情況然後更新左右兩端,若有更新,將更新的位置入隊,重複上述操作直到隊列爲空。