我的模板有个要小心的地方:
while (head + 1 != tail && slope(i - m + 1, q[tail - 1], q[tail - 2]))
q[tail++] = i - m + 1;
这一行,slope的第一个参数,是【马上将会push】的数字,这里也就是i-m+1。
这题上fread才AC,不然死活都T。哎。getchar过不了,float也过不了。。(精度卡这么严)
#include <cstdio>
#include <bits/stdc++.h>
#include <ctime>
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
typedef double LL;
const int maxn = 100000 + 100;
int n, m;
int a[maxn]={0};
LL s[maxn];
int q[maxn], tail, head;
LL f[maxn];
const LL inf = 1LL<<50;
/*
f[i][j] = f[k][j-1] + s[i]-s[k]
*/
int p;
LL y(int k)
{
return s[k];
}
LL x(int k)
{
return k;
}
bool slope(int i, int j, int k) //得出j,k斜率
{
//判断i,j的斜率,和j,k的斜率谁更大
//如果i,j斜率<=j,k斜率,那么就需要退了
return (y(i) - y(j)) * (x(j) - x(k)) <= (y(j) - y(k)) * (x(i) - x(j));
}
LL zhuan(int j, int i)//j<i,j向i转移的值
{
//return f[j] + (s[i] - s[j]) * (s[i] - s[j]) + m;
return (double)(s[i]-s[j])/(double)(i-j);
}
namespace IStream {
const int L = 1 << 15;
char buffer[L], *S, *T;
inline char get_char() {
if (S == T) {
T = (S = buffer) + fread(buffer, 1, L, stdin);
if (S == T) return EOF;
}
return *S++;
}
inline int get_int(int& tvalue) {//含有负数的整型读入, 成功返回1 失败返回EOF
char c;
int re = 0, sgn = 1;
for (c = get_char(); c != EOF && c != '-' && (c<'0' || c>'9'); c = get_char());
if (c == EOF) return EOF;
if (c == '-') { sgn = -1; c = get_char(); }
while (c >= '0' && c <= '9')
re=(re<<1)+(re<<3)+(c-'0'), c=get_char();
tvalue = sgn * re;
return 1;
}
}
using IStream::get_int;
void init()
{
tail = head = 0; //tail == head则为空
for (int i = 1; i <= n; ++ i) //scanf("%lf", &a[i]); //这里特别注意:用1下标
get_int(a[i]);
memset(s, 0, sizeof(s));
for (int i = 1; i <= n; ++ i) s[i] = s[i - 1] + a[i];
q[tail++] = 0;
}
void dp() //求f[...][p]
{
LL ans=0;
head = tail = 0;
q[tail++] = 0;
for (int i = m ; i <= n; ++ i)
{
while (head + 1 != tail && zhuan(q[head], i) <= zhuan(q[head + 1], i)) //如果队列里元素超过1个,那么就比较
++head;
f[i] = zhuan(q[head], i);
ans = max(ans, f[i]);
while (head + 1 != tail && slope(i - m + 1, q[tail - 1], q[tail - 2]))
{
--tail;
}
q[tail++] = i - m + 1;
}
if (m==0)ans=0;
printf("%.2f\n", ans);
}
void doit()
{
dp();
}
int main()
{
//double st = clock();
while (1)
{
if (get_int(n) == EOF) break;
if (get_int(m) == EOF) break;
//cout << n<< " "<<m<<endl;
init();
doit();
}
//cout << (clock()-st)/1000.0 << endl;
return 0;
}
/*
8 3
1 2 1 2 1 1 3 1
//ans = 1.75
*/