二分法
二分法除了可以求最大值最小值以外,还可以直接二分法凑答案
例题:https://ac.nowcoder.com/acm/contest/1000/A
题目大意:在一个长度为n的数组中,要求其中长度不小于f的一个子集使得这个子集的平均值达到最大
思路:这个最大平均值只可能在数组的最大值与最小值之间,通过二分法,每次测试一个答案。
测试一个答案是否满足的方法:用一个数组sum[i],记录前i项减去这个测试平均值的和,比如ary[] = {
6,4,2,10,3,8,5,9,4,1}测试3是不是答案 sum[0] = 3(6-3) sum[1] = 4(6+4-3-3)
推到公式:sum[i] = sum[i-1] + ary[i] - avg
通过sum数组可以判断前n项是否存在大于avg的字串
自己ac代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=43409223
他人blog:https://blog.nowcoder.net/n/e7dff46645fe4707b10eb941b96bc1a7
Farmer John's farm consists of a long row of N (1≤N≤100,000)fields. Each field contains a certain number of cows,1≤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 F (1≤F≤N) fields, where F given as input.
Calculate the fence placement that maximizes the average, given the constraint.
输入描述:
Line 1: Two space-separated integers, N and F.
Lines 2..N+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.
输出描述*:
Line 1: A single integer that is 1000 times the maximal average.Do not perform rounding, just print the integer that is 1000 * ncows / nfields 。
题目简化:
题目描述:
给定一个长度为n的非负整数序列A,求一个平均数最大的,长度不小于L的子段 。
输入描述:
第一行用空格分隔的两个整数n和L;
第二行为n个用空格隔开的非负整数,表示Ai。
输出描述:
输出一个整数,表示答案的1000倍。不用四舍五入,直接输出。
二分查找:
二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
思路:
可以先用二分查找到一个平均值avg来进行判定,能否成立一个子段大于等于F且大于等于这个平均值avg。
对于一段序列,每个数减去我们所算的平均数,如果大于0 那么他本身就大于平均数,如果小于0 那么它本身就小于平均数。
之后可以利用前缀和:s[i] = s[i - 1] + num[i] - avg。(关于这个式子怎么推出来的,我也表达不清楚(哭笑.jpg))如果这个前缀和中存在长度大于等于F且和大于等于0,就成立。