Description
有环行排列的n个仓库,每个仓库存有的货物数量分别是M1、M2、…、Mn,且 S=M1+M2+…+Mn 必为 n 的倍数。可以在任意一个仓库中取任意数量的货物搬运到相邻的仓库。
现在需要找到一种搬运方法,搬运最少的货物使得使每个仓库中的货物数目相同。
例如:n=4,每堆货物的数量分别为:17 9 14 16 4,我们进行如下搬运:
(1)仓库①向仓库②搬运1个货物;
(2)仓库①向仓库⑤搬运4个货物;、
(3)仓库③向仓库②搬运2个货物;
(4)仓库④向仓库⑤搬运4个货物;
搬运货物的总数是:1+4+2+4=11,并且可以证明这样的搬运方法是最佳搬运方法。
Input
第一行一个正整数 n (n<=10000),表示有n个仓库; 第二行 n 个整数(integer范围),表示n个仓库中货物数量;
Output
一个整数,表示最少搬运的货物数量。
Sample Input
5
17 9 14 16 4
Sample Output
11
思路
- 均分纸牌+变环为链
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 10005
using namespace std;
int n,a[maxn<<1],sum,b[maxn<<1],minn=0x7fffffff;
int main()
{
int n; scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]),sum+=a[i];
sum/=n;
for(int i=1;i<=n;++i) a[i]-=sum,a[i+n]=a[i];
for(int i=1;i<=n;++i)//枚举断点
{
int temp=0;
memcpy(b,a,sizeof(a));
for(int j=i;j<=i+n-1;++j)
if(b[j]!=0) b[j+1]+=b[j],temp+=abs(b[j]);
minn=min(minn,temp);
}
printf("%d
",minn);
return 0;
}