01 分数规划
01 分数规划指这样一类问题,对于每个元素,有
这样的问题可以二分答案
化简不等式会得到
这样一来,问题就转化为在该规则下选出的
例题:P1404 平均数
分析:可以用 01 分数规划的思想看待这个问题,这里认为每个元素的
二分答案后转化为选出的
注意精度问题,可以在刚开始把每个数都乘以
参考代码
#include <cstdio> #include <algorithm> using std::max; using std::min; using ll = long long; const int N = 100005; int a[N], n, m; ll sum[N], pre[N]; bool check(int x) { for (int i = 1; i <= n; i++) { sum[i] = sum[i - 1] + a[i] - x; pre[i] = min(pre[i - 1], sum[i]); } for (int i = m; i <= n; i++) if (sum[i] - pre[i - m] >= 0) return true; return false; } int main() { scanf("%d%d", &n, &m); int l = 0, r = 0, ans = 0; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); a[i] *= 1000; r = max(r, a[i]); } while (l <= r) { int mid = (l + r) / 2; if (check(mid)) { l = mid + 1; ans = mid; } else { r = mid - 1; } } printf("%d\n", ans); return 0; }
习题:P1419 寻找段落
解题思路
在上一题的基础上多了长度在
参考代码
#include <cstdio> #include <deque> using std::deque; const int N = 100005; const double INF = 1e4; const double EPS = 1e-5; int n, s, t, a[N]; double sum[N]; bool check(double x) { for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + (a[i] - x); deque<int> dq; for (int i = s; i <= n; i++) { while (!dq.empty() && dq.front() < i - t) dq.pop_front(); while (!dq.empty() && sum[dq.back()] > sum[i - s]) dq.pop_back(); dq.push_back(i - s); if (sum[i] - sum[dq.front()] > -EPS) return true; } return false; } int main() { scanf("%d%d%d", &n, &s, &t); double l = -INF, r = INF; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } while (r - l > EPS) { double mid = (l + r) / 2; if (check(mid)) { l = mid; } else { r = mid; } } printf("%.3f\n", l); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】