欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

AGC027B Garbage Collector

发布时间:2023/12/10 编程问答 60 豆豆
生活随笔 收集整理的这篇文章主要介绍了 AGC027B Garbage Collector 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

一道很好的构造题
原题链接
很快就能想到,捡每个垃圾的能量可以最后再算。然后,对于每个垃圾,在路上耗费的能量仅与它是第几个被捡的有关,于是我们考虑将垃圾分组。
首先,我们定义\(F(x,i)\)为某次从\(0\)出发,捡到坐标为\(x\)的垃圾的次序为\(i\)的花费,则有:

\(F(x,i)=\left\{\begin{matrix} 5x\ \ (i=1)\\ (2i-1)x\ \ (i>1) \end{matrix}\right.\)
由上式,易知对于每一组,让机器人先捡最右边的垃圾,然后往回一个一个捡是最优的。同时,将所有垃圾从后往前按一个固定的间隔\(k\)分组是最优的。
所以,我们只需要枚举\(k\),再利用前缀和,\(O(logn)\)计算组间距为\(k\)的花费,更新一下答案就行了。
为什么是\(O(logn)\)?因为调和级数的性质,\(\sum\limits_{i=1}^n\frac{1}{i}=logn+O(1)\)
因为中途计算时可能会爆\(long long\),所以我们要特判一下,当前的花费大于等于\(ans\)时就可以跳出循环了。
Code: #include <bits/stdc++.h>using namespace std;#define ll long longint n; ll x, ans = (ll)9e18, a[200005];int main() {cin >> n >> x;for(int i = 1; i <= n; ++i) cin >> a[i], a[i] += a[i-1];for(int k = 1; k <= n; ++k) {ll coef = 3LL, sum = 0;for(int i = n; i >= 1; i -= k) {sum += (a[i]-a[max(0, i-k)])*max(coef, 5LL), coef += 2;if(sum >= ans) break; //防爆long long}ans = min(ans, sum+(k+n)*x);}cout << ans << endl;return 0; }

转载于:https://www.cnblogs.com/dummyummy/p/9660416.html

总结

以上是生活随笔为你收集整理的AGC027B Garbage Collector的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。