搬运树苗(move)

来源:互联网 发布:linux 复制并覆盖 编辑:程序博客网 时间:2024/04/24 06:59

 搬运树苗(move)

输入文件:move.in

输出文件:move.out

【问题描述】

Neyc的绿化工程正在进行,树苗已经被工人送到园区内。设计师希望将树苗种植成一个环形的绿化带,这个绿化带有n个树苗群,而每个树苗群有相同数量的树苗。但是在卸放树苗时,工人虽然按环形排列将树苗放置了n堆,但是每一个树苗群的树苗数量却没有满足要求。

于是,需要从任意一个树苗群中取任意数量的树苗搬运到相邻的树苗群,使得每个树苗群树苗的数量相等。

为了节约时间,现在需要找到一种搬运方式:搬运最少的树苗使得每一个树苗群的树苗数目相同。

当然,每个树苗群的树苗数量是已知的,分别是m1,m2……….mn,且S=m1+m2….mn必为n的倍数。

例如:n=4,每个树苗群的树苗数量分别为17 9 14 16 4,我们进行如下搬运;

(1)    树苗群1向树苗群2搬运1棵树苗;

(2)    树苗群1向树苗群5搬运4棵树苗;

(3)    树苗群3向树苗群2搬运2棵树苗;

(4)    树苗群4向树苗群5搬运4棵树苗;

搬运树苗的总数是1+4+2+4=11,并且可以证明这样的搬运方式是最佳的搬运方法。

【输入格式】

第一行正整数n(n<=10000),表示有n个树苗群;

第二行n个整数(integer范围),表示n个树苗群的树苗数量。

【输出格式】

一个正整数,表示最少搬运树苗的数量。

【样例输入】

5

17 9 14 16 4

【样例输出】

11

=================

 将环拆成链......

================= 

var  n:longint;  tot,ans:int64;  m:array[0..20000]of longint;  f:array[0..20000]of int64;procedure init;begin  assign(input,'move.in');  assign(output,'move.out');  reset(input); rewrite(output);end;procedure terminate;begin  close(input); close(output);  halt;end;procedure main;var  i,j:longint;  rest:longint;begin  readln(n);  tot:=0;  for i:=1 to n do    begin      read(m[i]);      tot:=tot+m[i];    end;  for i:=1 to n do    m[n+i]:=m[i];  tot:=tot div n;  ans:=maxlongint;  fillchar(f,sizeof(f),0);  for i:=1 to n do    begin      rest:=0;      for j:=1 to n do        begin          inc(f[i],abs(rest));          rest:=rest+m[i+j-1]-tot;        end;      if f[i]<ans then ans:=f[i];    end;  writeln(ans);end;begin  init;  main;  terminate;end.
原创粉丝点击