
YbtOJ 二分算法课堂过关 例3 最大均值【二分】【前缀和】
发布日期:2021-05-07 13:09:45
浏览次数:20
分类:精选文章
本文共 1089 字,大约阅读时间需要 3 分钟。
思路
这道题显然需要二分一个平均值,
问题是小数怎么二分呢? 我们可以定义 l , r , m i d l,r,mid l,r,mid 为double类型, 并在判断时加上一个eps即可。(eps是在函数程序中事先声明的常量,是控制迭代精度的,相当于微积分里面的无限小值)这个问题解决了,我们发现还有一个问题:
判断当前二分到的平均值是否满足条件是 O ( n 2 ) O(n^2) O(n2),会超时。 首先想到前缀和优化。 此时判断区间为 max s u m i − s u m i − j + 1 ( l < i ≤ n , j ≤ i − l ) \max{sum_i-sum_{i-j+1}} (l<i≤n,j≤i-l) maxsumi−sumi−j+1(l<i≤n,j≤i−l) 不难发现 j j j 只会在 1 1 1~ i − l i-l i−l 中循环比较,直接 max \max max 即可,可以省掉一个for循环。 然后注意让当前区间的 s u m i − j + 1 sum_{i-j+1} sumi−j+1 最小即可得到较优答案。C o d e Code Code
#include#include #include using namespace std;const double eps=1e-6;double ans=0,a[100010];int n,k;bool check(double x){ double b[100010]; for(int i=1; i<=n; i++) b[i]=b[i-1]+(a[i]-x); double minn=0,boss=-2147483647; for(int i=k; i<=n; i++) { boss=max(boss,b[i]-minn); minn=min(minn,b[i-k+1]); } if(boss>=0) return 1; else return 0;}int main(){ cin>>n>>k; for(int i=1; i<=n; i++) scanf("%lf",&a[i]); double l=0,r=2000,mid=0; while(l+eps<=r) { mid=(l+r)/2; if(check(mid)) l=mid,ans=max(ans,mid); else r=mid; } cout<
发表评论
最新留言
做的很好,不错不错
[***.243.131.199]2025年03月27日 14时34分44秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Java开源博客My-Blog(SpringBoot+Docker)系列文章
2021-05-09
程序员视角:鹿晗公布恋情是如何把微博搞炸的?
2021-05-09
【JavaScript】动态原型模式创建对象 ||为何不能用字面量创建原型对象?
2021-05-09
Linux应用-线程操作
2021-05-09
多态体验,和探索爷爷类指针的多态性
2021-05-09
系统编程-进程间通信-无名管道
2021-05-09
记2020年初对SimpleGUI源码的阅读成果
2021-05-09
C语言实现面向对象方法学的GLib、GObject-初体验
2021-05-09
系统编程-进程-ps命令、进程调度、优先级翻转、进程状态
2021-05-09
为什么我觉得需要熟悉vim使用,难道仅仅是为了耍酷?
2021-05-09
一个支持高网络吞吐量、基于机器性能评分的TCP负载均衡器gobalan
2021-05-09
HDOJ2017_字符串统计
2021-05-09
高等软工第二次作业《需求分析阶段总结》
2021-05-09
404 Note Found 团队会议纪要
2021-05-09
CentOS安装Docker-ce并配置国内镜像
2021-05-09
使用JWT作为Spring Security OAuth2的token存储
2021-05-09
使用Redis作为Spring Security OAuth2的token存储
2021-05-09
【SOLVED】Linux使用sudo到出现输入密码提示延迟时间长
2021-05-09