1432:糖果传递
这是本蒟蒻 写的第一篇博客,若有不足请见谅
一本通原题链接
洛谷:P2512 [HAOI2008]糖果传递
【题目描述】
有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。
【输入】
第一行一个正整数n≤1000000,表示小朋友的个数.
接下来n行,每行一个整数ai,表示第i个小朋友得到的糖果的颗 数.
【输出】
求使所有人获得均等糖果的最小代价。
【输入样例】
4
1
2
5
4
【输出样例】
4
正解:
首先,最终每个小朋友的糖 果数量可以计算出来,等于糖果总数除以n,假设C1=A1减去最终每个小朋友的糖果数量,设Xi表示第i 个小朋友给了第i-1个小朋友Xi颗糖果, 我们希望Xi的绝对值之和尽量小,即 |X1| + |X1-C1| + |X1-C2| + ……+ |X1-Cn-1| 要尽量小。注意到|X1-Ci|的几何意义是数轴上的点X1到Ci的距离,所以问题变成了:给定数轴上的n个点,找出一个到他们的距离之和尽量小的点,而这个点就是这些数中的中位数,证明应该都懂。
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
long long a[1000100],x[1000100];//注意数据范围
long long mid,ans,n,sum;
int main()
{
scanf("%lld",&n);
for(long long i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum+=a[i];
}
sum/=n;//求最终每个小朋友的糖果数量可以计算出来
for(long long i=1;i<=n;i++)
x[i]=x[i-1]-a[i]+sum;
sort(x+1,x+1+n);
mid=x[(n+1)/2];//中位数
for(long long i=1;i<=n;i++)
ans+=abs(x[i]-mid);//求最小代价
printf("%lld",ans);
return 0;
}
这篇博客探讨了在信息学奥赛中的一道题目——糖果传递。问题描述为有n个小朋友围成一圈传递糖果,目标是使得每个小朋友最终拥有相同数量的糖果,且传递糖果的代价最小。博主通过分析指出,最小代价方案是让糖果数量等于总数除以n,然后通过调整分配,使糖果的转移绝对值之和最小,这个问题可以转化为寻找数轴上n个点的中位数,因为中位数到其他点的距离之和最小。
1061

被折叠的 条评论
为什么被折叠?



