[Haoi 2008] bzoj1045 糖果傳遞 [數學]

Description:
n 個小朋友坐成一圈,每人有ai 個糖果。每人只能給左右兩人傳遞糖果。每人每次傳遞一個糖果代價爲1 。求代價最小。


Solution:
設第i1 個人傳給第i 個人xi 個,那麼
xixi+1+ai=v
那麼我們得出
xi+1=xi+aiv
ci=vai
那麼
x2=x1c1
x3=x2c2=x1c1c2
ci 做前綴和
得出
xi=x1si1
那麼答案是
i=1n|si1x1|
自然x1s 的中位數時答案最小。


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;
int n;
ll v, ans;
ll a[maxn], s[maxn];
int read() {
    int x = 0, f = 1;
    char c = getchar();
    while(!isdigit(c)) {
        if(c == '-') {
            f = -1;
        }
        c = getchar();
    }
    while(isdigit(c)) {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x * f;
}
int main() {
    n = read();
    for(int i = 1; i <= n; ++i) {
        a[i] = read();
        v += a[i];
    }
    v /= n;
    for(int i = 2; i <= n; ++i) {
        s[i] = s[i - 1] + a[i] - v;
    }
    sort(s + 1, s + n + 1);
    ll t = s[(n + 1) / 2];
    for(int i = 1; i <= n; ++i) {
        ans += abs(s[i] - t);
    }
    printf("%lld\n", ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章