题目。


首先暴力很好搞,但是优化的话就不会了。放弃QWQ。

做法1:二分答案

然后发现平均值是$ave=\frac{sum}{len}$,这种形式似乎可以二分答案?把$len$移到左边。

于是二分$ave$,去找数列有没有区间和大于等于其$len$乘以$ave$的,然后卡住了。。

有一个很巧的转化,把每个数都减去一个$ave$,然后任意区间和就相当于把$ave$累加了$len$次。

于是乎只要看区间和$S-len*ave$是否大于等于0就可以了。

存在这样一个区间就说明$ave$可以更大,否则要小。查找存在性是一个简单的前缀和dp。

$O(nlogn)$。

poj精度死活卡不过去。

看来技巧还不够。

于是一气之下把所有double型全换成long long,也就是把小数点后五位通通看成整数,然后运算,最后除以100。

唉。

启示:关于平均数的题目很多时候都是用二分答案处理的。因为是分数形式。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. #define dbg(x) cerr << #x << " = " << x <<endl
  7. using namespace std;
  8. typedef long long ll;
  9. typedef double db;
  10. typedef pair<int,int> pii;
  11. template<typename T>inline T _min(T A,T B){return A<B?A:B;}
  12. template<typename T>inline T _max(T A,T B){return A>B?A:B;}
  13. template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
  14. template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
  15. template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
  16. template<typename T>inline T read(T&x){
  17. x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
  18. while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
  19. }
  20. const int N=1e5+;
  21. const db eps=1e-;
  22. ll A[N],s[N];
  23. ll L=,R,mid;
  24. int n,l;
  25. inline bool check(ll ave){
  26. for(register int i=;i<l;++i)s[i]=s[i-]+A[i]-ave;
  27. ll minx=1e16;
  28. for(register int i=l;i<=n;++i){
  29. MIN(minx,s[i-l]);s[i]=s[i-]+A[i]-ave;
  30. if(s[i]-minx>=)return ;
  31. }
  32. return ;
  33. }
  34.  
  35. int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
  36. read(n),read(l);
  37. for(register int i=;i<=n;++i)A[i]=read(A[i])*,MAX(R,A[i]);
  38. while(L<R){
  39. mid=L+R+>>;
  40. if(check(mid))L=mid;
  41. else R=mid-;
  42. }
  43. printf("%lld",(L/));
  44. return ;
  45. }

做法2:凸包优化

发现以每个点结尾的平均值$ave_i=\frac{S_i-S_j}{i-j}$  $0 \leq j \leq m$

于是想到斜率。问题变成:在前面的区间内找一点与$i$号点连线斜率最大。

然后发现上凸的3个点,中间那个没有用,所以维护一个下凸包。

查找的话是需要二分的,二分找下凸包里斜率$k_{i-1}<k_{i}>k_{i+1}$的这个点。

但是,基于这题并不是让求每个点结尾的最大平均数,而是全局的。

所以有这么一个神仙思路优化复杂度:

在查找时不要二分了,从队首开始比较,若$k_{l,i}<k_{l+1,i}$则弹出队首。

一直到找到这个最大斜率点,作为这个$i$的局部答案。

如果之后出现一个点,他和之前弹出过的点的斜率比目前没有弹出的点间的斜率都要大呢?

是有这种情况的。

但是,他不会影响全局最优解的形成,即使对于以$i$结尾算错了也没关系。

为什么呢。观察上面这种情况,在1点把下凸包前面一堆全弹掉了。发生这种情况当且仅当这个1号点在橙色线上方。

而2号点那种斜率最大的出现在已经弹出了的点里,必须满足在橙色线下方。

一旦有弹出,那么1号点决策一定比2号点的优。所以2号点算错了也不影响全局最大值。

所以这样的做法是$O(n)$获取全局最优解的。

所以网上说的都是并不严谨的。

这个$O(n)$做法正确性的证明是由hkk神仙提出来的,感谢!大家觉得好可以多去膜他。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. #define dbg(x) cerr << #x << " = " << x <<endl
  7. using namespace std;
  8. typedef long long ll;
  9. typedef double db;
  10. typedef pair<int,int> pii;
  11. template<typename T>inline T _min(T A,T B){return A<B?A:B;}
  12. template<typename T>inline T _max(T A,T B){return A>B?A:B;}
  13. template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
  14. template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
  15. template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
  16. template<typename T>inline T read(T&x){
  17. x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
  18. while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
  19. }
  20. const int N=1e5+;
  21. db ans;
  22. int n,m;
  23. int S[N],q[N],l=,r;
  24.  
  25. int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
  26. read(n),read(m);
  27. for(register int i=;i<=n;++i)S[i]=S[i-]+read(S[i]);
  28. for(register int i=m;i<=n;++i){
  29. while(l<r&&(S[i-m]-S[q[r]])*1ll*(q[r]-q[r-])<=(S[q[r]]-S[q[r-]])*1ll*(i-m-q[r]))--r;
  30. q[++r]=i-m;
  31. while(l<r&&(S[i]-S[q[l]])*1ll*(i-q[l+])<=(S[i]-S[q[l+]])*1ll*(i-q[l]))++l;
  32. MAX(ans,(db)(S[i]-S[q[l]])/(db)(i-q[l]));
  33. }
  34. printf("%d\n",(int)(ans*));
  35. return ;
  36. }

poj2018 Best Cow Fences[二分答案or凸包优化]的更多相关文章

  1. POJ-2018 Best Cow Fences(二分加DP)

    Best Cow Fences Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10174 Accepted: 3294 Desc ...

  2. loj#10012\poj2018 Best Cow Fences(二分)

    题目 #10012 「一本通 1.2 例 2」Best Cow Fences 解析 有序列\(\{a_i\}\),设\([l,r]\)上的平均值为\(\bar{x}\),有\(\sum_{i=l}^r ...

  3. POJ-2018 Best Cow Fences 二分

    题意:找到一个连续区间,区间的长度至少大于f,现在要求这个区间的平均值最大. 题解: 二分找答案. 每次对于2分的mid值, 都把原来的区间减去mid, 然后找到一长度至少为f的区间, 他们的区间和& ...

  4. POJ2018 Best Cow Fences 二分

    实数折磨人啊啊啊啊啊啊啊 好,实数应该是最反人类的东西了...... 这个害得我调了0.5天才过. 大意是这样的:给你一个数列,求其中不少于f个的连续数的最大平均值. 不禁想起寒假的课程来... 此处 ...

  5. POJ2018 Best Cow Fences —— 斜率优化DP

    题目链接:https://vjudge.net/problem/POJ-2018 Best Cow Fences Time Limit: 1000MS   Memory Limit: 30000K T ...

  6. bzoj 2402: 陶陶的难题II 二分答案维护凸包

    2402: 陶陶的难题II Time Limit: 40 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 68  Solved: 45[Submi ...

  7. Poj2018 Best Cow Fences

    传送门 题目大意就是给定一个长度为 n 的正整数序列 A ,求一个平均数最大的,长度不小于 L 的子序列. 思路: 二分答案. Code: #include<iostream> #incl ...

  8. poj2018——Best Cow Fences

    Description Farmer John's farm consists of a long row of N (1 <= N <= 100,000)fields. Each fie ...

  9. Poj 2018 Best Cow Fences(分数规划+DP&&斜率优化)

    Best Cow Fences Time Limit: 1000MS Memory Limit: 30000K Description Farmer John's farm consists of a ...

随机推荐

  1. 从gopath到go mod的一次尝试

    windows下的尝试: gomod初尝试下载官方包1.11(及其以上版本将会自动支持gomod) 默认GO111MODULE=auto(auto是指如果在gopath下不启用mod)go mod h ...

  2. golang 多级json转map

    func main() { jsonStr := `{"isSchemaConforming":true,"schemaVersion":0,"unk ...

  3. Jmeter使用CSV Data参数化,中文参数传递过程出现乱码问题

    解决方式:文件编码改为GB2312.GBK.GB18030(utf-8同样会乱码)

  4. 【HANA系列】SAP HANA SQL计算两个日期的差值

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL计算两个 ...

  5. UOJ#548.数学

    #include<iostream> #include<algorithm> #include<cmath> #include<cstdio> #inc ...

  6. ns2的第一个tcl脚本

    set ns [new Simulator] set tracef [open example1.tr w]$ns trace-all $tracefset namtf [open example1. ...

  7. (转)Linux中显示空闲内存空间的free命令的基本用法

    这篇文章主要介绍了Linux系统中free命令的基本用法,用free命令查看内存空余信息是Linux系统入门学习中的基础知识,需要的朋友可以参考下   free 命令显示系统使用和空闲的内存情况,包括 ...

  8. pycharm2019最新激活注册码(亲测有效)

    激活码一: 812LFWMRSH-eyJsaWNlbnNlSWQiOiI4MTJMRldNUlNIIiwibGljZW5zZWVOYW1lIjoi5q2j54mIIOaOiOadgyIsImFzc2l ...

  9. TCP三次握手笔记

    先了解OSI七层模型(OSI是Open System Interconnect的缩写,意为开放式系统互联) OSI层 功能 应用层 文件传输,电子邮件,文件服务,虚拟终端 表示层 数据格式化,代码转换 ...

  10. (一)Java秒杀项目之项目环境搭建

    一.Spring Boot环境搭建 1.把项目分成多个模块,每个模块对应一部分(不一定是一个章节)的内容,代码将在文章的具体位置给出,每个模块都是在之前模块的基础上构建,每个模块都为Spring Bo ...