题解 AT4376 [AGC027B] Garbage Collector
题目思路:
-
这道题我们可以枚举将它分成多少段, 显然对于每一段, 我们要将其中所有元素丢回来, 先捡这一段中距离原点最远的垃圾, 然后再在回来的路上捡起其他垃圾是最优的, 所以我们考虑如何去统计这个的贡献。
-
我们可以发现, 对于这一段来说, 它的贡献, 是每一个垃圾的距离乘上一个系数, 即:$ 5, 5, 7, 9, 11 $ , 然后加起来。
-
于是我们可以枚举这个 \(k\) , 然后用贪心的思想一起算这 \(k\) 段的贡献,即其中一共可以有 \(k∗2\) 个数的系数是 \(5\) ,\(k\) 个的系数是 \(7\) ,\(k\) 个的系数是 \(9\) ...然后这样一直算,统计答案就行了。
code:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 200005;
ll n, x, a[N], s[N], ans = LLONG_MAX;
int main() {
scanf("%lld %lld", &n, &x);
for (ll i=1; i<=n; i++) {scanf("%lld", &a[i]); s[i] = s[i - 1] + a[i];}
for (ll i=1; i<=n; i++) {
ll now = i * x;
for (ll j=0; j<=n / i; j++) {
ll y = n - i * j;
ll m = max(y - i, 0LL);
ll c;
if (j == 0) c = 5;
else c = j * 2 + 3;
now += c * (s[y] - s[m]);
if (now < 0) break;
}
if (now > 0) ans = min(ans, now);
}
printf("%lld\n", ans + n * x);
return 0;
}