Codeforces 578C Weakness and Poorness(二分 + 最大(小)子段和)
2015-09-28 22:47
260 查看
网上很多人写这道题目是三分+最大(小)子段和,但是这道题目是可以二分的,看我的二分内容
给出完整代码:
//我们的目的是让最小字段和和最大字段和相等 bool Calc(double x) { //MN、MX分别是最小最大子段和 if(MN > eps) return 1; //当最小子段和比0大时减小(-x)(ps:我是写的a[i] = a[i]+x) if(MX < eps) return 0; //当最大子段和比0小时增大(-x) return fabs(MN) - MX < eps;//当最小子段和比最大子段和小的时候让(-x)减小,反之增大。 } //以下是二分部分 mid = (l + r) / 2.0; if(Calc(mid)) r = mid; else l = mid;
给出完整代码:
#include<cstdio> #include<cmath> #define max(a, b) (a) > (b) ? (a) : (b) #define min(a, b) (a) < (b) ? (a) : (b) #define MAXN 200005 #define eps 1e-12 int n; double a[MAXN], MX, tmpx, MN, tmpn; bool Calc(double x) { MX = MN = tmpn = tmpx = a[1] + x; for(int i = 2; i <= n; i ++) { tmpx = max(tmpx + a[i] + x, a[i] + x); MX = max(tmpx, MX); tmpn = min(tmpn + a[i] + x, a[i] + x); MN = min(tmpn, MN); } if(MN > eps) return 1; if(MX < eps) return 0; return fabs(MN) - MX < eps; } int main() { scanf("%d", &n); for(int i = 1; i <= n; i ++) scanf("%lf", a + i); double l = -10000.0000001, r = 10000.0000001, mid; for(int i = 1; i <= 60; i ++) { mid = (l + r) / 2.0; if(Calc(mid)) r = mid; else l = mid; } printf("%.9lf", MX); return 0; }
相关文章推荐
- Dijkstra 图最短路径算法
- POJ - 1661 Help Jimmy(DP)
- DOM操作(0926)
- Codeforces 578C Weakness and Poorness(二分 + 最大(小)子段和)
- C# WebBrowser 控件的使用
- HTTP协议
- 2. Java基础语法
- Linux 环境下Oracle PRO*C程序的编写简单范例
- C/C++ printf函数参数的执行顺序
- 重写boost内存池
- uC/OS-II 函数之邮箱管理相关函数
- 0928练习作业
- 可以实现视图之间相互传值、信息交换的方法总结
- 【原创】GC/垃圾回收简介
- POCO C++例程整理--有关线程 推荐
- 主机SSH连接Kali虚拟机
- 在linux上安装mysql
- uC/OS-II 函数之邮箱管理相关函数
- [WCF REST] Web消息主体风格(Message Body Style)
- bzoj4096 [Usaco2013 dec]Milk Scheduling