题解【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
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;
}