您的位置:首页 > 编程语言

欢乐暑假线上编程比赛第四题:分配糖果

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++):

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: