BZOJ1045 糖果传递

转载~~

环形纸牌分配问题

前段时间TYVJ的某场模拟赛好似有这个题、、模型就是环形的均分纸牌、、

这个题目其实主要是数学分析啦、、

从线性的均分纸牌出发、令a[i]为纸牌树,k为每堆的目标牌数、

记p[i]=k-a[i]+p[i-1] 含义就是第i堆需要从后一堆拿的纸牌、

那么对p数组求和就是答案了、

对这个环形的、我们这样考虑、

记sum[i]=sigma(p[j]-p[j-1])  j<=i 那么可以得到p[1]=p[i]-sum[i] 即 p[i]=sum[i]+p[1]

又因为最后的答案ans=sigma p[i]=sigma (s[i]+p[1]) 即数轴上s数组的点到-p[1]的距离之和、

而s数组中的值的集合在取任一点为起点的时候都是不变的、

所以当p[1]为该数组中的中位数时ans最小、

剩下的就是写代码啦~

 

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdlib>
 
using  namespace  std;
 
int  a[1000001],p[1000001];
long  long  ans,tot,now,n;
 
int  main(){
     scanf ( "%d" ,&n);
     for  ( int  i=0;i<n;i++)  scanf ( "%d" ,&a[i]),tot+=a[i];
     tot/=n;
     for  ( int  i=1;i<n;i++) p[i]=p[i-1]+tot-a[i];
     sort(p,p+n);
     now=p[n/2];
     for  ( int  i=0;i<n;i++) ans+= abs (p[i]-now);
     printf ( "%lld\n" ,ans);
     //while(1);
     return  0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值