P2115 [USACO14MAR] Sabotage G(二分/思维)
要求得到平均产奶量的最小值,想到二分答案。
emm...但是我在如何判断当前
还是要想到本质上,可以试着用数学式子表达当前
若当前要删除
到这里应该是最简式子了。
而知道
也就是说,
那不就 一定有 :
所以
因此,思路也就来了,构建新的数组表达
在此上,由于从中间删除,则需要求一个前缀和一个后缀和,同时分别维护最小值,
最后注意,头和尾不能删,也不能一个都不删。
#include <bits/stdc++.h> #define re register int #define min(x, y) (x < y ? x : y) using namespace std; typedef double db; const int N = 1e5 + 10; const db eps = 1e-5, inf = 0x3f3f3f3f; int n; db a[N], l, r, b[N], s1[N], s2[N], s1min[N], s2min[N]; bool check(db mid) { for (re i = 0; i <= n + 1; i ++) s1min[i] = inf, s2min[i] = inf; for (re i = 1; i <= n; i ++) b[i] = a[i] - mid; for (re i = 1; i <= n; i ++) { s1[i] = s1[i - 1] + b[i]; s1min[i] = min(s1min[i - 1], s1[i]); } for (re i = n; i ; i --) { s2[i] = s2[i + 1] + b[i]; s2min[i] = min(s2min[i + 1], s2[i]); } for (re i = 1; i <= n - 2; i ++) { if (s1min[i] + s2min[i + 2] <= 0) return true; } return false; } void search() { l = 1, r = N; while (l + eps < r) { db mid = (l + r) / 2; if (check(mid)) r = mid; else l = mid; } } int main() { scanf("%d", & n); for (re i = 1; i <= n; i ++) cin >> a[i]; search(); printf("%.3lf\n", l); return 0; }
类似: P1419 寻找段落
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具