题目1550:分糖果
时间限制:1秒
内存限制:32 兆
特殊判题:否
提交:996
解决:234
- 题目描述:
给从左至右排好队的小朋友们分糖果,
要求:
1.每个小朋友都有一个得分,任意两个相邻的小朋友,得分较高的所得的糖果必须大于得分较低的,相等则不作要求。
2.每个小朋友至少获得一个糖果。
求,至少需要的糖果数。
输入:
输入包含多组测试数据,每组测试数据由一个整数n(1<=n<=100000)开头,接下去一行包含n个整数,代表每个小朋友的分数Si(1<=Si<=10000)。
- 输出:
对于每组测试数据,输出一个整数,代表至少需要的糖果数。
- 样例输入:
- 3
1 10 1
3
6 2 3
2
1 1 - 样例输出:
- 4
- 5
- 2
图的简单应用,用数组模拟图。注意RUNTIME_ERROR,即数组边界和栈溢出的问题。
#include<stdio.h> const int left=0; const int right=1; int s[100005]; int f[100005][2]; int c[100005]; int n; int refresh(int k) //从i点向两边更新。如果用DFS容易栈溢出,RUNTIME_ERROR,尽量用while替代DFS。 { int i=k; while (f[i][left]==1) { if (c[i-1]<=c[i]) c[i-1]=c[i]+1; i=i-1; } i=k; while (f[i][right]==1) { if (c[i+1]<=c[i]) c[i+1]=c[i]+1; i=i+1; } return 0; } int main() { while (scanf("%d",&n)!=EOF) { for (int i=0;i<n;i++) { f[i][left]=0; f[i][right]=0; c[i]=0; } for (int i=0;i<n;i++) scanf("%d",&s[i]); if (s[1]>s[0]) f[0][right]=1;//初始化f[i][left]表示i左边是否存在比它大的数,f[i][right]表示i右边是否存在比它大的数 for (int i=1;i<n-1;i++) { if (s[i-1]>s[i]) f[i][left]=1; if (s[i+1]>s[i]) f[i][right]=1; } if (s[n-2]>s[n-1]) f[n-1][left]=1; if (f[1][left]==0) { c[0]=1; refresh(0); } for (int i=1;i<n-1;i++) if (f[i-1][right]==0 && f[i+1][left]==0) { c[i]=1; refresh(i); } if (f[n-2][right]==0) { c[n-1]=1; refresh(n-1); } long sum=0; for (int i=0;i<n;i++) sum+=c[i]; printf("%ld\n",sum); } return 0; }