1045: [HAOI2008] 糖果传递 - BZOJ

Description

有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。
Input

小朋友个数n 下面n行 ai
Output

求使所有人获得均等糖果的最小代价。
Sample Input
4
1
2
5
4

Sample Output
4
数据规模
30% n<=1000
100% n<=1000000

 

说难又不难,我对数学题没什么感觉啊

首先,均分纸牌都做过吧(什么,没做过!?百度NOIP2002均分纸牌)

这个只是环形而已,为了把它变成环形,我们要知道a1给了an多少

不妨设a1给an的糖果数为k

那我们的答案就是ans=k+|a1-k-average|+|a1+a2-k-2*average|+|a1+a2+a3-k-3*average|+......+|a1+a2+a3+......+a(n-1)-k-(n-1)*average|

前面的k可以看成|0-k|

所以我求的就是|0-k|+|a1-k-average|+|a1+a2-k-2*average|+|a1+a2+a3-k-3*average|+......+|a1+a2+a3+......+a(n-1)-k-(n-1)*average|的最小值

这个就是一道经典的奥赛题了,k取中位数时最小,排个序就行了

 1 const
 2     maxn=1000010;
 3 var
 4     b:array[0..maxn]of int64;
 5     a:array[0..maxn]of longint;
 6     n:longint;
 7     x,k,ans:int64;
 8 
 9 procedure init;
10 var
11     i:longint;
12 begin
13     read(n);
14     for i:=1 to n do
15       begin
16         read(a[i]);
17         inc(x,a[i]);
18       end;
19     x:=x div n;
20 end;
21 
22 procedure sort(l,r:longint);
23 var
24     i,j:longint;
25     t,y:int64;
26 begin
27     i:=l;
28     j:=r;
29     y:=b[(l+r)>>1];
30     repeat
31       while b[i]<y do
32         inc(i);
33       while b[j]>y do
34         dec(j);
35       if i<=j then
36       begin
37         t:=b[i];
38         b[i]:=b[j];
39         b[j]:=t;
40         inc(i);
41         dec(j);
42       end;
43     until i>j;
44     if i<r then sort(i,r);
45     if j>l then sort(l,j);
46 end;
47 
48 procedure work;
49 var
50     i:longint;
51 begin
52     b[1]:=0;
53     for i:=2 to n do
54       b[i]:=b[i-1]+a[i-1]-x;
55     sort(1,n);
56     k:=b[(n+1)>>1];
57     for i:=1 to n do
58       inc(ans,abs(b[i]-k));
59     write(ans);
60 end;
61 
62 begin
63     init;
64     work;
65 end.
View Code

 

转载于:https://www.cnblogs.com/Randolph87/p/3649724.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值