有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。
标签:原理 gif 传递 pac output ace view log out
有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。
求使所有人获得均等糖果的最小代价。
这道题对于最终小朋友手中的糖的数量我们是可以算出来的,我们用ave来表示
我们假设Gi表示第i个人给第i-1个人糖的数量,G1表示第1个人给第n个人
那么最后答案就是|G1|+|G2|+···+|Gn|
那么到最后
第一个人的糖就是A1-G1+G2=ave
第二个人的糖就是A2-G2+G3=ave
······
第n个人的糖就是An-Gn+G1=ave
这里我们假设Ci=Ci-1+Ai-ave
所以通过第一个人的糖,我们可以推出G2=G1-C1
通过第二个人,可以推出G3=G1-C2
······
第n个人,可以推出Gn=G1-Cn-1
所以最后答案就变成了|G1|+|G1-C1|+|G1-C2|+···+|G1-Cn-1|
对于求最后答案,问题就变成了给你坐标轴上的n个点,要你找到一个点,使得这个点到所有的点的距离之和最小
而这个点的坐标就是坐标轴上点的中位数
1 #include<bits/stdc++.h> 2 #define N 1000005 3 #define ll long long 4 using namespace std; 5 int n,ave; 6 ll sum,ans; 7 int a[N],c[N]; 8 int main(){ 9 scanf("%d",&n); 10 for (int i=1;i<=n;i++){ 11 scanf("%d",&a[i]); 12 sum+=a[i]; 13 } 14 ave=sum/n; 15 for (int i=2;i<=n;i++) 16 c[i]=c[i-1]+a[i]-ave; 17 sort(c+1,c+1+n); 18 int mid=c[(n>>1)+1]; 19 for (int i=1;i<=n;i++) 20 ans+=abs(mid-c[i]); 21 printf("%lld\n",ans); 22 return 0; 23 }
BZOJ-1045-[HAOI2008] 糖果传递(中位数原理)
标签:原理 gif 传递 pac output ace view log out
原文地址:http://www.cnblogs.com/zhuchenrui/p/7718758.html