题解 AT4376 [AGC027B] Garbage Collector

题目由此去luogu

题目由此去2_AtCoder


题目思路:

  • 这道题我们可以枚举将它分成多少段, 显然对于每一段, 我们要将其中所有元素丢回来, 先捡这一段中距离原点最远的垃圾, 然后再在回来的路上捡起其他垃圾是最优的, 所以我们考虑如何去统计这个的贡献。

  • 我们可以发现, 对于这一段来说, 它的贡献, 是每一个垃圾的距离乘上一个系数, 即:$ 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;
} 
posted @ 2021-10-12 00:05  铭矾  阅读(66)  评论(0)    收藏  举报