这题直接贪心就能过
让 i 从 F 开始 到 N 结束 表示 我选择的区间的末尾位置
而 开头位置 不过 就是 从 1 到 i - p + 1选一个最优的
看过程
就让 j 从 1 到 i - p + 1 每次看一下(j, i - p + 1这一段的均值是否 小于 我总共的均值 如果小于
就让 j++ 并且当i增加的时候j继续看就行
证明一下为什么贪心对
假设 当 i = x 的时候 我已经抛弃了 角标为 1 和 角标 为 2
那么 当 i = x+1 的时候 我一定不会选择 角标为 1 或者 2
因为 如果 当 i 等于 x + 1的时候 均值变小 一定不是最优解 而均值比原来的大那么一定也不选 1 和 2 因为均值比这个小的时候都不选 那么大了肯定也不选
C++ 代码
#include <iostream>
#include <algorithm>
#define rep(i, a, b) for (int i = a; i <= b; ++i)
using namespace std;
const int maxn = 1e5 + 5;
double a[maxn];
int main() {
int n, p;
cin >> n >> p;
rep(i, 1, n) {
cin >> a[i];
a[i] += a[i - 1];
}
double max_ = -9999.999;
int j = 1;
double jun;
rep(i, p, n) {
jun = (a[i] - a[j - 1]) / (i - j + 1);// 这是目前的均值加上可以抛弃的长度
double cha = (a[i - p] - a[j - 1]) / (i - p - j + 1);//可以抛弃的部分的均值
while (i - j + 1 > p && cha <= jun) { // 开始抛弃
j++;
cha = (a[i - p] - a[j - 1]) / (i - p - j + 1); // 每次抛弃的时候均值会改变
}
jun = (a[i] - a[j - 1]) / (i - j + 1);//抛弃完毕 这里就是 以i为结尾的最大均值
max_ = max(max_, jun);
}
cout << int(max_ * 1000);
return 0;
}