P4016 负载平衡问题
题目描述
GG 公司有 nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使 nn 个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。
输入输出格式
输入格式:
文件的第 11 行中有 11 个正整数 nn ,表示有 nn 个仓库。
第 22 行中有 nn 个正整数,表示 nn 个仓库的库存量。
输出格式:
输出最少搬运量。
输入输出样例
说明
1≤n≤100
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int N=1e6+5; int n,s; long long a[N],sum[N],ave; inline long long read() { char c=getchar();long long num=0; for(;!isdigit(c);c=getchar()); for(;isdigit(c);c=getchar()) num=num*10+c-'0'; return num; } int main() { n=read(); for(int i=1;i<=n;++i) { a[i]=read(); ave+=a[i]; } ave/=n; for(int i=1;i<=n;++i) sum[i]=sum[i-1]+a[i]-ave; sort(sum+1,sum+n+1); long long T=sum[n/2+1],ans=0; for(int i=1;i<=n;++i) ans+=abs(sum[i]-T); printf("%lld",ans); return 0; }
设第i个小朋友从他左边小朋友那里得到 li 个糖果,向他右边的小朋友传递 ri 个糖果
(li 与 ri 都可以为负数)
显然 li=ri−1 ,特殊地 l1=rn
设p为最终每个小朋友手中的糖果数
则有 li+ai−ri=p , 即 ri=li+(ai−p)
而我们又有 li=ri−1
一直递归下去有 ri=l1+(a1−p)+(a2−p)+(a3−p)+…+(ai−p)
最终答案为 |r1|+|r2|+…+|rn|
我们可以记下 ai−p 的前缀和为 sumi
那么 ans=|l1+sum1|+|l1+sum2|+…+|l1+sumn|
设第i个小朋友从他左边小朋友那里得到 li 个糖果,向他右边的小朋友传递 ri 个糖果
(li 与 ri 都可以为负数)
显然 li=ri−1 ,特殊地 l1=rn
设p为最终每个小朋友手中的糖果数
则有 li+ai−ri=p , 即 ri=li+(ai−p)
而我们又有 li=ri−1
一直递归下去有 ri=l1+(a1−p)+(a2−p)+(a3−p)+…+(ai−p)
最终答案为 |r1|+|r2|+…+|rn|
我们可以记下 ai−p 的前缀和为 sumi
那么 ans=|l1+sum1|+|l1+sum2|+…+|l1+sumn|
绝对值是个美妙的东西,|l1+sumi| 可想为数轴上 −li 与 sumi 的距离
那么ans的最小值在 −l1 取 sumi 中位数时取到
求出sumi及其中位数后计算即可。