標籤:des style blog http java color
MAX Average ProblemTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5855 Accepted Submission(s): 1456
Problem DescriptionConsider a simple sequence which only contains positive integers as a1, a2 ... an, and a number k. Define ave(i,j) as the average value of the sub sequence ai ... aj, i<=j. Let’s calculate max(ave(i,j)), 1<=i<=j-k+1<=n.
InputThere multiple test cases in the input, each test case contains two lines.
The first line has two integers, N and k (k<=N<=10^5).
The second line has N integers, a1, a2 ... an. All numbers are ranged in [1, 2000].
OutputFor every test case, output one single line contains a real number, which is mentioned in the description, accurate to 0.01.
Sample Input
10 66 4 2 10 3 8 5 9 4 1
Sample Output
6.50
Source2009 Multi-University Training Contest 19 - Host by BNU
題意:即求一段長度大於等於K且平均值最大的子串的平均值。
思路:斜率最佳化入門題,推薦04年國家集訓隊周源的論文(這題為例題講解),子串s+1到t的平均值為(sum[t]-sum[s])/(t-s);這個可以看做直線的斜率,根據它具有的性質來最佳化,具體見論文。注意算斜率盡量用乘法算。
代碼:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <map>#include <stack>#include <vector>#include <set>#include <queue>#pragma comment (linker,"/STACK:102400000,102400000")#define maxn 100005#define MAXN 200005#define mod 1000000009#define INF 0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-6typedef long long ll;using namespace std;int n,m,ans,cnt,tot,flag;int a[maxn],sum[maxn];int q[maxn];double res;void solve(){ int i,j,t,cur; int head=0,tail=-1; double pre,dx1,dy1,dx2,dy2; res=0; for(i=m; i<=n; i++) { cur=i-m; while(head<tail) { dy1=sum[cur]-sum[q[tail]]; dx1=cur-q[tail]; dy2=sum[q[tail]]-sum[q[tail-1]]; dx2=q[tail]-q[tail-1]; if(dy1*dx2<=dx1*dy2) tail--; else break ; } q[++tail]=cur; while(head<tail) { dy1=sum[i]-sum[q[head]]; dx1=i-q[head]; dy2=sum[i]-sum[q[head+1]]; dx2=i-q[head+1]; if(dy1*dx2<=dx1*dy2) head++; else break ; } res=max(res,(sum[i]-sum[q[head]]+0.0)/(i-q[head]+0.0)); // 不能寫dy1/dx1 上一個迴圈可能不進入 } printf("%.2f\n",res);}int main(){ int i,j,t; while(~scanf("%d%d",&n,&m)) { sum[0]=0; for(i=1; i<=n; i++) { scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; } solve(); } return 0;}