1.4.6 Best Cow Fences(solution+discuss)

举报
irrational 发表于 2022/01/18 00:27:09 2022/01/18
【摘要】 大家好,这又是一道二分题,首先来看题面。   Description Farmer John's farm consists of a long row of NNN ( 1≤N≤1051 \le N \le 10^51≤N≤105)fields. Each field contains a ce...

大家好,这又是一道二分题,首先来看题面。

 

Description

Farmer John's farm consists of a long row of NNN ( 1≤N≤1051 \le N \le 10^51≤N≤105)fields. Each field contains a certain number of cows, 1≤ncows≤20001 \le ncows \le 20001≤ncows≤2000.

FJ wants to build a fence around a contiguous group of these fields in order to maximize the average number of cows per field within that block.

The block must contain at least FFF (1≤F≤N1 \le F \le N1≤F≤N) fields, where FFF given as input.

Calculate the fence placement that maximizes the average, given the constraint.

给定正整数数列A,求一个平均数最大的,长度不小于L的(连续的) 子段。

Input

  • Line 1: Two space-separated integers, NNN and FFF.

  • Lines 222..N+1N+1N+1: Each line contains a single integer, the number of cows in a field. Line 2 gives the number of cows in field 1,line 3 gives the number in field 2, and so on.

Output

  • Line 1:A single integer that is  1000  \;1000\;1000times the maximal average.Do not perform rounding, just print the integer that is 1000×ncows/n1000\times ncows/n1000×ncows/n fields.

Sample Input 1

10 6 
6  
4  
2  
10  
3  
8  
5  
9  
4  
1 

Sample Output 1

6500 

Hint

1  ≤  N  ≤  100,0001  \le  N  \le  100,0001  ≤  N  ≤  100,000

1  ≤  ncows  ≤  20001  \le  ncows  \le  20001  ≤  ncows  ≤  2000


  
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,f;
  4. double line[100010];//正整数数列A
  5. double sum[100010];//前缀和
  6. double b[100010];//储存数列A减去当前数值
  7. /*
  8. 题解:对平均数进行二分,找出减去当前平均数的前缀和sum[i]-min_val的值得到答案ans来判断可否实现。-Megumin
  9. */
  10. int main()
  11. {
  12. scanf("%d %d", &n, &f);
  13. for (int i = 1; i <= n; i++)
  14. {
  15. scanf("%lf", &line[i]);
  16. }
  17. double eps = 1e-5;
  18. double l = -1e6, r = 1e6;
  19. while(r-l > eps)
  20. {
  21. double mid = (l+r) / 2;
  22. for (int i = 1; i <= n; i++)
  23. b[i] = line[i] - mid;
  24. for (int i = 1; i <= n; i++)
  25. sum[i]=sum[i-1]+b[i];//obj 1前缀和处理
  26. //以下是记录
  27. double ans = -1e10;//保存当前的答案
  28. double min_val = 1e10;//保存当前的前缀和最小值
  29. for (int i = f; i <= n; i++)
  30. {
  31. min_val = min(min_val, sum[i - f]);//obj 2当处理i的时候我们最短可以减掉哪里的sum值?
  32. ans = max(ans, sum[i] - min_val);//obj 3答案是怎么算出来的?
  33. }
  34. if(ans>=0)//obj 4二分处理
  35. l=mid;
  36. else
  37. r=mid;
  38. }
  39. printf("%d",(int)(r*1000));
  40. return 0;
  41. }

需要思考三个问题:

1、


  
  1. for (int i = 1; i <= n; i++)
  2. sum[i]=sum[i-1]+b[i];//obj 1前缀和处理
  3. //以下是记录
  4. double ans = -1e10;//保存当前的答案
  5. double min_val = 1e10;//保存当前的前缀和最小值
  6. for (int i = f; i <= n; i++)
  7. {
  8. min_val = min(min_val, sum[i - f]);//obj 2当处理i的时候我们最短可以减掉哪里的sum值?
  9. ans = max(ans, sum[i] - min_val);//obj 3答案是怎么算出来的?
  10. }

这里sum[i-1]+b[i]是想干什么?b[i]是干什么用的?

2、


  
  1. if(ans>=0)//obj 4二分处理
  2. l=mid;
  3. else
  4. r=mid;

l,r在二分的时候为什么不用加一or减一?

 想了解详情,笔者之后会更新,请您多多关注~

文章来源: blog.csdn.net,作者:irrationality,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_54227557/article/details/120583656

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。