程序员发橘子

题目描述

每年的 1024 程序员节日,黑马程序员都会举办大型的庆祝活动。今年的程序员节也不例外,每个班级的同学都发了橙子。

班级里有 n 名同学从前到后排成一排,且已经得知了这些同学的成绩,其中第 i名同学的成绩是 ai班主任想根据同学们上个阶段的考试成绩来评定发橙子的数量。为了激励成绩优秀同学,发橙子时需要满足如下要求:

  • 相邻同学中成绩好的同学的橙子必须更多。若相邻的同学成绩一样,则它们分到的数量必须平等。
  • 每个同学至少分配一个橙子

由于预算有限,班主任希望在符合要求的情况下发出尽可能少的橙子。请问,至少需要准备多少橙子呢?

输入格式

第一行是一个不超过 10^6正整数 n,表示学生数量。

接下来一行有 n 个不超过 10^9 的非负整数 ai,表示第 i 个同学的成绩。

输出格式

输出答案,也就是需要最少准备多少个橙子。

输入样例:

11
3 6 9 4 7 7 2 13 15 15 19

输出样例:

24

 

 思路:这是一个正向和反向的不减子列,初始化每个人有一个橘子,接着遍历数组,后一个比前一个成绩高,则橘子也多一,接着反向再遍历一遍数组,也是求不减子列,最后累加数组求和。

#include <cstdio>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <math.h>
#include <map>
using namespace std;
const int inf=999999;//0x7fffff
const long long mod=1e9+7;
const double PI=acos(-1);

long long n,m;
long long ans=0;
bool vis[105];
long long dis[10000000],get[10000000];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>dis[i];
        get[i]=1;                                  //初始化get数组,因为每个学生最少有1个橘子 
    }
    for(int i=2;i<=n;i++){                           //从左向右扫一遍数组,相当于从左向右寻找不减子列  
        if(dis[i]>dis[i-1]){                      // 如果后一个学生分数大于前一个学生 橘子数也比前一个学生橘子多一个
            get[i]=get[i-1]+1;
        }
        else if(dis[i]==dis[i-1]){                  //分数相等橘子数也应该相等 
            get[i]=get[i-1];
        }
    }
    for(int i=n-1;i>=1;i--){                     //接着再从右向左扫一遍数组,也是从右向左找不减子列 
        if(dis[i]>dis[i+1]){
            get[i]=max(get[i],get[i+1]+1);         // 同样的,成绩高的比旁边成绩低的橘子数多一个  但要考虑第一次排序结果,所有取此次结果和上一次结果的较大者 
        }
        else if(dis[i]==dis[i+1]){               //分数相等橘子数也应该相等 
            get[i]=get[i+1];
        }
    }
    for(int i=1;i<=n;i++){                    //累加求橘子数 
        ans+=get[i];
    }
    cout<<ans;
    return 0;
}

 

 

posted @ 2020-04-16 22:02  Maxwell·  阅读(468)  评论(0编辑  收藏  举报