1. 程式人生 > >HDU 2993 MAX Average Problem(斜率DP經典+輸入輸出外掛)

HDU 2993 MAX Average Problem(斜率DP經典+輸入輸出外掛)

ref double getchar nbsp inline 外掛 () 解題思路 .cn

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2993

題目大意:給出n,k,給定一個長度為n的序列,從其中找連續的長度大於等於k的子序列使得子序列中的平均值最小。

解題思路:斜率DP經典題,

詳細分析見: NOI2004年周源的論文《淺談數形結合思想在信息學競賽中的應用》 還有要註意要用輸入輸出外掛,不是getchar()版的,是fread()版的,第一次遇到這麽變態的題目- -|||。 代碼:
 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4
#include<stdio.h> 5 using namespace std; 6 const int N=1e5+5; 7 8 int q[N],head,tail; 9 long long sum[N]; 10 11 double Slope(int k,int j){ 12 return double(sum[j]-sum[k])/(j-k); 13 } 14 //輸入輸出外掛 15 const int BUF=25000000; 16 char Buf[BUF],*buf=Buf; 17 template <class T> 18
inline void read(T &a){ 19 for(a=0;*buf<48;buf++); 20 while(*buf>47) 21 a=a*10+*buf++-48; 22 } 23 24 int main(){ 25 int n,k; 26 int tot=fread(Buf,1,BUF,stdin); 27 while(1){ 28 if(buf-Buf+1>=tot)break; 29 read(n),read(k); 30 for
(int i=1;i<=n;i++){ 31 read(sum[i]); 32 sum[i]+=sum[i-1]; 33 } 34 double ans=0; 35 head=tail=0; 36 q[tail++]=0; 37 for(int i=k;i<=n;i++){ 38 while(head+1<tail&&Slope(q[head],i)<=Slope(q[head+1],i)){ 39 head++; 40 } 41 ans=max(ans,Slope(q[head],i)); 42 int j=i-k+1; 43 while(head+1<tail&&Slope(q[tail-2],q[tail-1])>=Slope(q[tail-1],j)){ 44 tail--; 45 } 46 q[tail++]=j; 47 } 48 printf("%.2f\n",ans); 49 } 50 return 0; 51 }

HDU 2993 MAX Average Problem(斜率DP經典+輸入輸出外掛)