小米食堂每年都会举办一次厨艺大赛,假设参赛的厨师一共有n位(n < 1000),比赛结束后没有公布评分,但是站在领奖台上的一排厨师中每位厨师都能看到与自己相邻的厨师(左或者右)里评分比自己低(看不到比自己分数高的人的分数)的评分。比赛结束之后要发奖金,以1K为单位,每位厨师至少会发1K的奖金,另外,如果一个厨师发现自己的奖金没有高于比自己评分低的厨师的奖金,就会不满意,作为比赛组织方,小米食堂至少需要发放多少奖金才能让所有厨师满意。
输入描述:
每组数据为n+1个正整数单空格分割,其中第一个数为参赛厨师的人数,后面n个数为每位厨师的得分(0-100)
输出描述:
输出至少需要多少K的奖金
示例1
输入
10 60 76 66 76 85 55 61 71 84 62
输出
20
结题思路:这道题类似于leetcode的分糖果问题。下面附上leecode分糖果问题的原题
There are N children standing in a line. Each child is assigned a rating value.
You are giving candies to these children subjected to the following requirements:
- Each child must have at least one candy.
- Children with a higher rating get more candies than their neighbors.
What is the minimum candies you must give?
根据题目的意思,我们可以知道我们可以知道为了让分到的糖果有等级区别,可以从左边往右看,要比左边比自己等级低的分的糖果多,从右边往左看,也要比自己等级低的分的糖果多。然后取两者之间的较大值。
具体算法如下:
初始化所有小孩糖数目为1,从左往右后扫描,如果第i个小孩等级比第i-1个高,那么i的糖数目等于i-1的糖数目+1;从右往左扫描,如果第i个的小孩的等级比i+1个小孩高,但是糖的数目却小或者相等,那么i的糖数目等于i+1的糖数目+1。
同样的,该题厨师分奖金问题也可以这么理解:把小孩子的糖理解成厨师的奖金,厨师的分数理解为小孩子的等级。代码如下:
import java.util.Scanner; public class XiaoMI { public static void main(String args[]){ Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int scores[]=new int[n]; for(int i=0;i<n;i++){ scores[i]=sc.nextInt(); } // System.out.println(countSaraly(scores,0,n-1)); System.out.println(testSaraly(scores)); } //按照分糖果的思想来 public static int testSaraly(int scores[]){ if(scores==null||scores.length==0) return 0; int length=scores.length; int money[]=new int[length]; int sum=0; //初始值为1 money[0]=1; //从左往右 for(int i=1;i<length;i++){ if(scores[i]>scores[i-1]) money[i]=money[i-1]+1; else money[i]=1; } sum+=money[length-1]; //从右往左 for(int i=length-2;i>=0;i--){ if(scores[i]>scores[i+1]){ //以下更新money,取从左往右和从右往左的最大值 money[i]=money[i+1]+1>money[i]?money[i+1]+1:money[i]; } //对奖金进行累加 sum+=money[i]; } return sum; } }
时间复杂度是O(N),两个遍历,空间复杂度也是O(N),新建了一个数组。