BZOJ 1045 糖果传递 题解 【递推乱搞就对了
BZOJ 1045 糖果传递 题解 【递推乱搞就对了
1045: [HAOI2008] 糖果传递
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 3505 Solved: 1626
[Submit][Status][Discuss]Description
有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。
Input
第一行一个正整数n<=987654321,表示小朋友的个数.接下来n行,每行一个整数ai,表示第i个小朋友得到的
糖果的颗数.Output
求使所有人获得均等糖果的最小代价。
Sample Input
4
1
2
5
4Sample Output
4HINT
Source
这道题在codevs有类似的题目(均分纸牌),但是这个是一个环形的。
主要思路来源于hzw大神的博客(%%%%).
最好自己拿笔算一遍。
Ac代码
#include<cstdio> #include<algorithm> #include<cmath> using namespace std; int A[1000010]; int C[1000010]; long long sum,avr,ans; int read(int &x){ char c=getchar(),last;x=0; while(c<'0'||c>'9')last=c,c=getchar(); while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=getchar(); if(last=='-')x=-x; return x; } int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&A[i]),sum+=A[i]; avr=sum/n; for(int i=2;i<=n;i++) C[i]=C[i-1]+A[i]-avr; sort(C+1,C+n+1); int m=C[(n>>1)+1]; for(int i=1;i<=n;i++) ans+=abs(C[i]-m); printf("%lld",ans); return 0; }