您的位置:首页 > 其它

HDU 2993 MAX Average Problem(斜率优化DP)

2013-09-22 23:22 447 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993

题目大意:给定一个长度为n(最长为10^5)的正整数序列,求出连续的最短为k的子序列平均值的最大值。

[align=left]Sample Input[/align]

10 6
6 4 2 10 3 8 5 9 4 1

[align=left]Sample Output[/align]

6.50

分析:斜率优化DP,要认真看

代码如下:

# include<iostream>
# include<cstdio>
# include<cstring>
# include<algorithm>

using namespace std;

const int maxn = 100010;
double a[maxn], sum[maxn];
int n,k;
int q[maxn],head,tail;

//读入优化,否则超时
int GetInt()
{
char ch=getchar();
while(ch<'0' || ch>'9')
ch = getchar();
int num = 0;
while(ch >= '0' && ch<='9')
{
num = num*10 + ch - '0';
ch = getchar();
}
return num;
}

void DP()
{
head = tail =0;
double ans = -1;
for(int i=k; i<=n; i++)
{
int j = i-k;
//维护下凸
while(tail - head >=2)
{
double x1 = j - q[tail-1];
double y1 = sum[j] - sum[q[tail-1]];
double x2 = q[tail-1] - q[tail-2];
double y2 = sum[q[tail-1]] - sum[q[tail-2]];
if(x1 * y2 - y1 *x2 >= 0)
tail--;
else
break;
}
q[tail++] = j;
//寻找最优解并删除无用元素
while(tail - head >=2)
{
double x1 = i - q[head];
double y1 = sum[i] - sum[q[head]];
double x2 = i - q[head+1];
double y2 = sum[i] - sum[q[head+1]];
if(x1*y2 - y1*x2 >= 0)
head ++;
else
break;
}
double tmp = (sum[i] - sum[q[head]])/(i-q[head]);
ans = max(ans, tmp);
}
printf("%.2lf\n",ans);
}

int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&k)!=EOF)
{
sum[0] = 0;
for(int i=1; i<=n; i++)
{
a[i] = GetInt();
sum[i] = sum[i-1] + a[i];
}
DP();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: