AGC027B Garbage Collector
生活随笔
收集整理的这篇文章主要介绍了
AGC027B Garbage Collector
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
一道很好的构造题
原题链接
很快就能想到,捡每个垃圾的能量可以最后再算。然后,对于每个垃圾,在路上耗费的能量仅与它是第几个被捡的有关,于是我们考虑将垃圾分组。
首先,我们定义\(F(x,i)\)为某次从\(0\)出发,捡到坐标为\(x\)的垃圾的次序为\(i\)的花费,则有:
由上式,易知对于每一组,让机器人先捡最右边的垃圾,然后往回一个一个捡是最优的。同时,将所有垃圾从后往前按一个固定的间隔\(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的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 动态链接(指向运行时常量池的方法引用)
- 下一篇: 方法的绑定机制-静态绑定和动态绑定