题解【Codeforces1253C】Sweets Eating

题面

题意简述:

\(n\) 颗糖果,每一颗糖果的糖分为 \(a_i\),第 \(j\) 天吃第 \(i\) 颗糖果会损失 \(j\times a_i\) 的糖分。

已知 Yui 每一天最多吃 \(m\) 颗糖果,她想要知道她总共吃 \(1,2,\dots,n\) 颗糖果时最少损失多少糖分。

\(\texttt{Data Range: }1\le m\le n\le 2\times 10^5, 1\le a_i\le 2\times 10^5\)

很明显的贪心。

首先对糖果按照 \(a_i\) 升序排序。

容易发现要吃 \(i\) 块糖果时一定要吃前 \(i\) 块。

根据排序不等式,我们发现糖分更多的糖果要最先吃。

然后就是一个前缀和可以搞定的事了,建议手玩理解更深刻。

注意要开 \(\texttt{long long}\)

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

inline int gi()
{
    int f = 1, x = 0; char c = getchar();
    while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
    while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return f * x;
}

const int INF = 0x3f3f3f3f, N = 200003, M = N << 1;

int n, m;
int a[N];
LL sum, cf[N];

int main()
{
    n = gi(), m = gi();
    for (int i = 1; i <= n; i+=1) 
    	a[i] = gi();
    sort(a + 1, a + 1 + n);
    for (int i = 1; i <= n; i+=1)
    	cf[i] = a[i];
    for (int i = m + 1; i <= n; i+=1)
    	cf[i] += cf[i - m];
    for (int i = 1; i <= n; i+=1)
    	printf("%lld ", sum += cf[i]);
    return 0;
}
posted @ 2020-06-03 22:16  csxsi  阅读(223)  评论(0编辑  收藏  举报