首页 > 代码库 > hdu 2993 MAX Average Problem (斜率优化dp入门)
hdu 2993 MAX Average Problem (斜率优化dp入门)
MAX Average Problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5855 Accepted Submission(s): 1456
Problem Description
Consider 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.
Input
There 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].
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].
Output
For every test case, output one single line contains a real number, which is mentioned in the description, accurate to 0.01.
Sample Input
10 6 6 4 2 10 3 8 5 9 4 1
Sample Output
6.50
Source
2009 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-6 typedef 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; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。