思路:直接写出表达式 sum[i]-sum[j]/(i-j)
发现是个斜率的式子,所以考虑直接用斜率优化来做。
其余部分根简单,只要注意要维护一个长度不超过k的区间,在入队的时候需要处理成 i-k+1的形式。
代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn=1e5+6;
int n,m;
int a[maxn];
int sum[maxn];
double dp[maxn];
int q[maxn];
double solve(int i,int j)
{
return 1.0*(sum[i]-sum[j])/(i-j);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
scanf("%d%d",&n,&m);
sum[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
int head,tail;
head=tail=0;
double ans=0;
for(int i=m;i<=n;i++)
{
while(head<tail&&solve(i,q[head])<solve(i,q[head+1]))
{
head++;
}
dp[i]=1.0*(sum[i]-sum[q[head]])/(i-q[head]);
ans=max(ans,dp[i]);
int k=i-m+1;//为了维护最多有m个
while(head<tail&&solve(q[tail],q[tail-1])>solve(k,q[tail]))
{
tail--;
}
q[++tail]=k;
}
printf("%d\n",int(ans*1000));
return 0;
}