hdu 2993 MAX Average Problem

斜率dp,主要是结合求下凸包的性质

#include <STDIO.H>
#include <STRING.H>
#include <algorithm>
using namespace std;
/*
	dp[i] = max{(sum[i]-sum[j])/(i-j) } (i-j >= k)
	等于点(i,sum[i])与点(j,sum[j])间的斜率

	斜率dp
	每次更新i时,更新凸包
*/
const int MAXN = 100005;
inline double max(double a, double b)
{
	return a>b?a:b;
}
double sum[MAXN];
int q[MAXN];
double input()
{
	char c;
	double res = 0.0;
	do 
	{
		c = getchar();
	} while ( c < '0' || c > '9');

	do 
	{
		res = res*10 + (c - '0');
		c = getchar();
	} while ( c >= '0' && c <= '9');
	return res;
}
double cross(int a, int b, int c)
{
	return (sum[b]-sum[a])*(c-a) - (sum[c]-sum[a])*(b-a);
}
int main()   
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
	int n, k;
	int i, j;
	int head;
	while (scanf("%d%d", &n, &k) == 2)
	{
		sum[0] = 0.0;
		for (i = 1; i<= n; ++i)
			sum[i] = sum[i-1]+input();
		double res = 0, tp;
		head = 0;
		q[head++] = 0;	// 从0开始
		for (i = k; i<= n; ++i)
		{
			j = i-k;	// 更新最短距离处的点
			while (head>1 && cross(q[head-2],q[head-1],j)>0)
				--head;
			q[head++] = j;
			// 二分寻找最大值
			int mid;
			int a, b;
			a = 0, b = head-1;
			while (a < b)
			{
				mid = (a+b)>>1;
				if (cross(q[mid],q[mid+1],i) > 0)
					b = mid;
				else
					a =mid+1;
			}
			tp = (sum[i]-sum[q[a]])/(i-q[a]);
			res = max(res, tp);
		}
		printf("%.2lf\n", res);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值