货物搬运-贪心

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;
}
原文地址:https://www.cnblogs.com/wuwendongxi/p/13334900.html