HDU 2993 MAX Average Problem (斜率优化)
ACM
题目地址:
HDU 2993 MAX Average Problem
题意:
给一个长度为 n 的序列,找出长度 >= k 的平均值最大的连续子序列。
分析:
斜率优化的例题。
这里有篇博客给论文里面的分析部分上色了,还不错:http://www.cnblogs.com/Free-rein/archive/2012/08/09/2630190.html
数据有点多,得用输入外挂才能过。
代码:
/*
* Author: illuz <iilluzen[at]gmail.com>
* File: 2993.cpp
* Create Date: 2014-09-17 23:56:17
* Descripton: dp
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define repf(i,a,b) for(int i=(a);i<=(b);i++)
typedef long long ll;
const int N = 1e5 + 5;
ll sum[N];
int q[N], front, rear;
int n, k;
inline bool check(int a, int b, int c) {
return (sum[c] - sum[b]) * (b - a) <= (sum[b] - sum[a]) * (c - b);
}
int Scan() {
int res = 0, ch, flag = 0;
if((ch = getchar()) == '-')
flag = 1;
else if(ch >= '0' && ch <= '9')
res = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
int main() {
while (~scanf("%d%d", &n, &k)) {
repf (i, 1, n) {
sum[i] = sum[i - 1] + Scan();
}
front = 0;
rear = -1;
double ans = 0;
repf (i, k, n) {
while (front < rear && check(q[rear - 1], q[rear], i - k))
rear--;
q[++rear] = i - k;
while (front < rear && check(q[front + 1], q[front], i))
front++;
ans = max(ans, (sum[i] - sum[q[front]]) * 1. / (i - q[front]));
}
printf("%.2f\n", ans);
}
return 0;
}