hdu 2993 MAX Average Problem (斜率优化,超神读入挂)
题意:给一个长度为 n 的序列,找出长度 >= k 的平均值最大的连续子序列。
思路:dp到时没有很多,主要的还是斜率优化,详情看,NOI2004年周源的论文《浅谈数形结合思想在信息学竞赛中的应用》
代码:
这个题好像还可以进行二分查找,日后再补吧,这超神读入挂的确有点强
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=100010; double sum[maxn]; int q[maxn]; bool check(int i,int j,int k) { i=q[i],j=q[j]; double aa=(sum[j]-sum[i])/(j-i),bb=(sum[k]-sum[j])/(k-j); return aa>=bb; } double max(double a,double b){ return a>b?a:b; } namespace fastIO { #define BUF_SIZE 100000 //fread -> read bool IOerror = 0; inline char nc() { static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE; if(p1 == pend) { p1 = buf; pend = buf + fread(buf, 1, BUF_SIZE, stdin); if(pend == p1) { IOerror = 1; return -1; } } return *p1++; } inline bool blank(char ch) { return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; } inline void read(int &x) { char ch; while(blank(ch = nc())); if(IOerror) return; for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0'); } #undef BUF_SIZE }; using namespace fastIO; double slop(int i,int k){ i=q[i]; return (sum[k]-sum[i])/(k-i); } int main(){ int n,k; while(read(n),read(k),!IOerror){ sum[0]=0; int i,j; for(i=1;i<=n;i++){ int a;read(a); sum[i]=sum[i-1]+a; } int head=0,rear=0; double ans=0; for(i=k;i<=n;i++){ j=i-k; while(head<rear && check(rear-1,rear,j)) rear--; q[++rear]=j; while(head<rear && slop(head+1,i)>=slop(head,i)) head++; ans=max(ans,slop(head,i)); } printf("%.2f\n",ans); } return 0; }