欢乐暑假线上编程比赛第四题:分配糖果
2014-08-21 06:25
211 查看
题目详情
有n个小朋友站成一排(编号从0到n-1),每个小朋友有一个rating值,存放在ratings数组中。老师需要给他们分
配糖果,每个小朋友至少需要一颗糖果,对于任意相邻的两个小朋友i和i+1,rating值大的必须比rating值小的分
配的糖果多(rating相同的没必要分配一样多的糖果)。
请计算最少需要多少颗糖果,才能完成上述分配。
输入格式:
多组数据,每组数据第一行是一个正整数n。
接下来n行,每行有1个正整数,表示每个小朋友的rating值。所有整数都不超过100000。
输出格式:
每组数据一行,包括一个正整数,表示做少需要的糖果数。
参考思路:V字形序列就是严格单调递增然后严格单调递减的序列,可以没有前面的严格单调递增或者后面的严格
单调递减。对于任何一个数组序列,都是由多个V字形序列链接而成的,对于每个V字形序列,除了左右最高点以
外,每个端点分配的糖果数只与它距离最低点的距离有关,最低点分配一个糖果,然后左右递增,对于左最高点,
它应该分配的糖果数为前一个V字形里面应该得的糖果数和该V字形里面应该得的糖果数的较大值,右最高点同理。
具体实现起来有多种方法。
通过了的源代码(c++):
有n个小朋友站成一排(编号从0到n-1),每个小朋友有一个rating值,存放在ratings数组中。老师需要给他们分
配糖果,每个小朋友至少需要一颗糖果,对于任意相邻的两个小朋友i和i+1,rating值大的必须比rating值小的分
配的糖果多(rating相同的没必要分配一样多的糖果)。
请计算最少需要多少颗糖果,才能完成上述分配。
输入格式:
多组数据,每组数据第一行是一个正整数n。
接下来n行,每行有1个正整数,表示每个小朋友的rating值。所有整数都不超过100000。
输出格式:
每组数据一行,包括一个正整数,表示做少需要的糖果数。
参考思路:V字形序列就是严格单调递增然后严格单调递减的序列,可以没有前面的严格单调递增或者后面的严格
单调递减。对于任何一个数组序列,都是由多个V字形序列链接而成的,对于每个V字形序列,除了左右最高点以
外,每个端点分配的糖果数只与它距离最低点的距离有关,最低点分配一个糖果,然后左右递增,对于左最高点,
它应该分配的糖果数为前一个V字形里面应该得的糖果数和该V字形里面应该得的糖果数的较大值,右最高点同理。
具体实现起来有多种方法。
通过了的源代码(c++):
#include <iostream> #include <algorithm> #include <cmath> #include <queue> using namespace std; typedef long long lld; inline lld getSum(int n) { return (lld)(1 + n) * n / 2; } inline int yourMax(int a, int b) { return a > b ? a : b; } const int inf = 0x7fffffff; const int MAXN = 100000; int array[MAXN]; int n; int pos[MAXN], flag[MAXN]; int pn; void getPosAndFlag() { pos[0] = 0; if(array[0] <= array[1]) { flag[0] = 0; }else { flag[0] = 2; } int i, j; pn = 1; for(i=1; i<n-1; i++) { if(array[i] > array[i-1] && array[i] > array[i+1]) { flag[pn] = 3; pos[pn++] = i; } else { if(array[i] == array[i-1] && array[i] > array[i+1]) { flag[pn] = 2; pos[pn++] = i; } else { if(array[i] > array[i-1] && array[i] == array[i+1]) { flag[pn] = 1; pos[pn++] = i; } else { if(array[i] <=array[i-1] && array[i] <= array[i+1]) { flag[pn] = 0; pos[pn++] = i; } } } } } if(array[n-1] > array[n-2]) { flag[pn] = 1; pos[pn++] = n-1; } else { flag[pn] = 0; pos[pn++] = n-1; } } lld solve() { lld res = 0; for(int i=0; i<pn; i++) { switch(flag[i]) { case 0: if(i == 0) { res += getSum(pos[i+1] - pos[i]); } else { if(i == pn-1) { res += getSum(pos[i] - pos[i-1]); } else { res += getSum(pos[i] - pos[i-1]) + getSum(pos[i+1] - pos[i]) - 1; } } break; case 1: res += pos[i] - pos[i-1] + 1; break; case 2: res += pos[i+1] - pos[i] + 1; break; case 3: res += yourMax(pos[i]-pos[i-1]+1, pos[i+1]-pos[i]+1); break; default: break; } } return res; } int main() { while(scanf("%d", &n)!=EOF) { int i, j; for(i=0; i<n; i++) scanf("%d", &array[i]); if(n == 1) { printf("1\n"); continue; } getPosAndFlag(); printf("%lld\n", solve()); } return 0; }
相关文章推荐
- 欢乐暑假线上编程比赛第四题:分配糖果
- 欢乐暑假线上编程比赛第四题:分配糖果(解答)
- 欢乐暑假线上编程比赛第一题:拆点游戏
- 欢乐暑假线上编程比赛第一题:拆点游戏
- 欢乐暑假线上编程比赛第三题:轮换数
- 欢乐暑假-高校俱乐部暑期线上编程竞赛奖励机制
- 欢乐暑假-高校俱乐部暑期线上编程竞赛奖励机制
- 金色十月线上编程比赛第二题:解密
- 金色十月线上编程比赛第二题:解密
- 金色十月线上编程比赛第一题:小女孩数数
- CSDN挑战编程——《金色十月线上编程比赛第二题:解密》
- 金色十月线上编程比赛第一题:小女孩数数
- 金色十月线上编程比赛第二题:解密
- CSDN之金色十月线上编程比赛第一题:小女孩数数
- 金色十月线上编程比赛第一题:小女孩数数
- CSDN之金色十月线上编程比赛第二题:解密
- 金色十月线上编程比赛第二题:解密
- CSDN挑战编程——《金色十月线上编程比赛第一题:小女孩数数》
- 金色十月线上编程比赛第一题:小女孩数数
- 金色十月线上编程比赛第一题:小女孩数数