开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
[传智杯 #2 初赛] 1024 程序员节发橙子
题目描述
每年的 1024 程序员节日,黑马程序员都会举办大型的庆祝活动。今年的程序员节也不例外,每个班级的同学都发了橙子。
班级里有 名同学从前到后排成一排,且已经得知了这些同学的成绩,其中第 名同学的成绩是 。班主任想根据同学们上个阶段的考试成绩来评定发橙子的数量。为了激励成绩优秀同学,发橙子时需要满足如下要求:
- 相邻同学中成绩好的同学的橙子必须更多。若相邻的同学成绩一样,则它们分到的数量必须平等。
- 每个同学至少分配一个橙子
由于预算有限,班主任希望在符合要求的情况下发出尽可能少的橙子。请问,至少需要准备多少橙子呢?
输入格式
第一行是一个整数 ,表示学生数量。
接下来一行有 个整数,第 个整数 ,表示第 个同学的成绩。
输出格式
输出答案,也就是需要最少准备多少个橙子。
样例 #1
样例输入 #1
5
3 4 5 4 3
样例输出 #1
9
提示
样例 1 解释
每位同学拿到的橙子的数量分别是 ,所以至少需要准备 个。
数据规模与约定
对于全部的测试点,保证 ,。
解题思路
- 仔细查看题目你会发现,这道题有点像一个波浪,也就是一下子递增一下子递减,我们只要记录它正向递增和逆向递减所造成的橙子变化即可
- 正向看
- 如果前一项比后一项大,那么前一项的橘子数较后一项加一(相当于前缀和的思路)
- 如果前一项和后一项相等,那么前一项的橘子树对于后一项橘子数
- 逆向看
- 如果后一项比前一项大,那么后一项有一个判断
- 即后一项是不是正向的驼峰,如果是的话得判断是前一项加一大还是后一项大
- 总结下来就是一个max来判断
- 如果后一项和前一项一样大,那么后一项等于前一项
- 如果后一项比前一项大,那么后一项有一个判断
- 累加输出
代码展示
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int a[N], w[N];
long long res;
int main()
{
int n;
cin >> n;
//存储及初始化
for (int i = 1; i <= n; i++)cin >> a[i], w[i] = 1;
//正向标记
for (int i = 2; i <= n; i++) {
if (a[i] > a[i - 1])w[i] = w[i - 1] + 1;
if (a[i] == a[i - 1])w[i] = w[i - 1];
}
//逆向标记
for (int i = n; i >= 2; i--) {
if (a[i - 1] > a[i])w[i - 1] = max(w[i - 1], w[i] + 1);
if (a[i - 1] == a[i])w[i - 1] = w[i];
}
//求和
for (int i = 1; i <= n; i++)res += w[i];
cout << res;
return 0;
}
PS:这是一道有点意思的题目~