(贪心+推导) 糖果传递

 来源:《算法竞赛进阶指南》,微软面试题 , HAOI2008


输入样例:

4
1
2
5
4

输出样例:

4

 

 注解:

        Xi 可能为正可能为负, 不过不影响, 我们要求的是绝对值之和

经过推导, 需要求的目标变为👇

 且有

 

这可以抽象为, 找出数轴上的点到(c1,c2,c3......cn)这些点的绝对距离之和的最小值, 经过分析, 取中间点可以得到最小值.

代码实现:

#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
const int N = 1e6+10;

LL a[N], c[N];
int main()
{
    int n;
    scanf("%d", &n);
    
    LL sum = 0, avg;
    for(int i = 1; i <= n; i ++) {
        scanf("%d", &a[i]);
        sum += a[i];
    }
    avg = sum / n;
    
    c[n] = 0;
    for(int i = 1; i < n; i ++) c[i] = c[i-1] + avg - a[i];
    sort(c+1, c+n+1);
    
    LL res = 0;
    for(int i = 1; i <= n; i ++) res += abs(c[i]-c[(n+1)>>1]);
    
    cout << res;
    
    return 0;
}

posted @ 2022-03-15 08:51  泥烟  阅读(35)  评论(0编辑  收藏  举报