hdu2993之斜率dp+二分查找

MAX Average Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 5825    Accepted Submission(s): 1446

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].

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

参考:kuangbin--hdu2993

直接斜率DP:O(N)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <cmath>
#include <map>
#include <iomanip>
#define INF 99999999
typedef long long LL;
using namespace std;

const int MAX=100000+10;
int n,k;
int s[MAX],q[MAX];
double dp[MAX],sum[MAX];

double GetY(int i,int j){
	return sum[i]-sum[j];
}

int GetX(int i,int j){
	return i-j;
}

double DP(){
	int head=0,tail=1;
	q[head]=0;
	double ans=0;
	for(int i=1;i<=n;++i)sum[i]=sum[i-1]+s[i]*1.0;
	for(int i=k;i<=n;++i){
		int j=i-k;
		while(head+1<tail && GetY(j,q[tail-1])*GetX(q[tail-1],q[tail-2])<=GetY(q[tail-1],q[tail-2])*GetX(j,q[tail-1]))--tail;
		q[tail++]=j;
		while(head+1<tail && GetY(i,q[head])*GetX(i,q[head+1])<=GetY(i,q[head+1])*GetX(i,q[head]))++head;
		dp[i]=(sum[i]-sum[q[head]])/(i-q[head]);
		ans=max(ans,dp[i]);
	}
	return ans;
}

int input(){//加速外挂
	char ch=' ';
	int num=0;
	while(ch<'0' || ch>'9')ch=getchar();
	while(ch>='0' && ch<='9')num=num*10+ch-'0',ch=getchar();
	return num;
}

int main(){
	while(~scanf("%d%d",&n,&k)){
		for(int i=1;i<=n;++i)s[i]=input();
		printf("%0.2lf\n",DP());
	}
	return 0;
}

斜率DP+二分查找:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <cmath>
#include <map>
#include <iomanip>
#define INF 99999999
typedef long long LL;
using namespace std;

const int MAX=100000+10;
int n,k;
int s[MAX],q[MAX];
LL sum[MAX];

LL GetY(int i,int j){
	return sum[i]-sum[j];
}

int GetX(int i,int j){
	return i-j;
}

LL check(int mid,int i){
	return GetY(i,q[mid+1])*GetX(q[mid+1],q[mid])-GetY(q[mid+1],q[mid])*GetX(i,q[mid+1]);
}

int search(int l,int r,int i){
	//由于斜率单调递增
	/*int top=r;
	while(l<=r){//根据i与mid的斜率 和 i与mid+1的斜率之差求切点
		if(l == r && l == top)return q[l];//这里一定要注意如果切点是最后一个点需要另判,因为mid+1不存在会出错
		int mid=(l+r)>>1;
		if(check(mid,i)<0)r=mid-1;
		else l=mid+1;
	}*/
	while(l<r){//根据i与mid的斜率 和 i与mid+1的斜率之差求切点
		int mid=(l+r)>>1;
		if(check(mid,i)<0)r=mid;
		else l=mid+1;
	}
	return q[l];
}

double DP(){
	int head=0,tail=1,p;
	q[head]=0;
	double ans=0,dp;
	for(int i=1;i<=n;++i)sum[i]=sum[i-1]+s[i];
	for(int i=k;i<=n;++i){
		int j=i-k;
		while(head+1<tail && GetY(j,q[tail-1])*GetX(q[tail-1],q[tail-2])<=GetY(q[tail-1],q[tail-2])*GetX(j,q[tail-1]))--tail;
		q[tail++]=j;
		p=search(head,tail-1,i);//根据相邻点与i点的斜率之差二分查找切点
		dp=(sum[i]-sum[p])*1.0/(i-p);
		if(dp>ans)ans=dp;
	}
	return ans;
}

int input(){//加速外挂
	char ch=' ';
	int num=0;
	while(ch<'0' || ch>'9')ch=getchar();
	while(ch>='0' && ch<='9')num=num*10+ch-'0',ch=getchar();
	return num;
}

int main(){
	while(~scanf("%d%d",&n,&k)){
		for(int i=1;i<=n;++i)s[i]=input();
		printf("%0.2lf\n",DP());
	}
	return 0;
}

hdu2993之斜率dp+二分查找

时间: 2024-08-22 15:25:24

hdu2993之斜率dp+二分查找的相关文章

usaco No Change, 2013 Nov 不找零(二分查找+状压dp)

Description 约翰带着 N 头奶牛在超市买东西,现在他们正在排队付钱,排在第 i 个位置的奶牛需要支付 Ci 元.今天说好所有东西都是约翰请客的,但直到付账的时候,约翰才意识到自己没带钱,身上只有 K 张消费卡,第 i 张卡里有 Vi 元余额. 问题是,这些消费卡都是一次性的,它们可以被收银机读取,但如果卡一旦离开了收银机,卡里 的余额就会归零,而且超市也不负责找零!奶牛的队伍很长,不可能再调整她们的位置了,所以一张 卡只能支付一段连在一起的账单.而且,一张账单只能用一张消费卡支付,超

【二分查找最优解】FZU 2056 最大正方形

题意:现在有一个n*m的矩阵A,在A中找一个H*H的正方形,使得其面积最大且该正方形元素的和不大于 limit. 分析:开始以为是DP或者二维RMQ,其实用二分就可以做出来: 在输入时构造元素和矩阵dp[][](即dp[i][j]为从(1,1)到(i,j)的矩形范围元素和);再在(0,min(m,n))范围内二分查找满足条件的最优解H:计算正方形内元素和的方法要掌握; 注意二分时要避免出现L==M而死循环的情况. 代码如下: 1 #include<iostream> 2 #include<

有序数组中的二分查找

最近看一些算法题发现这些问题到最后落实到编程实现上都是一种基础的体现,包括对基本的for,if,else,while等语句的理解程度,还有对循环递归的理解.所以还是得回归最基本的算法,现在去学习那些高深复杂的DP,KMP,红黑树未免有点好高骛远.目前应该坚持基础,打好基础,毕竟不是CS科班出身.言归正传,二分查找就是一个最基础的算法.它的时间复杂度O(logn).分为迭代实现和递归实现两种,如下:程序没有经过很多测试,应该有bug,欢迎指正. int BinarySearch(int * a,

二分查找小结

在弄dp时感觉一道题需非要弄清二分查找不可.以前学二分一直就很迷惑,网上资料也各种各样.的确二分是个很容易写错的算法,今天只好不算太耐心的再看一遍二分.总感觉时间不够用.. 二分查找有许多细节,这次先抓主要矛盾.关于什么(left+rigth)/2溢出的问题啊先不考虑了.对我来说二分迷惑的地方还是在1.while(left?right) ?处到底是<还是<= 2.判断后mid到底是加一还是减一还是不变? 3.返回left还是right? 这次大概明白了一些,因为二分查找是看区间开闭的,对于左闭

杭电 1025 Constructing Roads In JGShining&#39;s Kingdom(二分查找)

http://acm.hdu.edu.cn/showproblem.php?pid=1025 Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 15515    Accepted Submission(s): 4412 Problem Descriptio

NYOJ 720 DP+二分

项目安排 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时间,假设做完每个项目后,拿到报酬都是不同的.由于小明马上就要硕士毕业了,面临着买房.买车.给女友买各种包包的鸭梨,但是他的钱包却空空如也,他需要足够的money来充实钱包.万能的网友麻烦你来帮帮小明,如何在最短时间内安排自己手中的项目才能保证赚钱最多(注意:做项目的时候,项目不能并行,即两个项目之间不能有时间重叠,

POJ 2182 Lost Cows (树状数组 &amp;&amp; 二分查找)

题意:给出数n, 代表有多少头牛, 这些牛的编号为1~n, 再给出含有n-1个数的序列, 每个序列的数 ai 代表前面还有多少头比 ai 编号要小的牛, 叫你根据上述信息还原出原始的牛的编号序列 分析:如果倒着看这个序列的话, 那序列的最后一个元素就能够确定一个编号.举个例子:如果序列的最后一个元素为0, 那就说明这头牛前面再也没有比它编号更小的牛了, 所以这头牛的编号肯定是最大的, 我们只要给它所在的编号加个标记, 然后继续根据倒数第二个.第三个--来依次确定便可还原整个序列, 这里可以使用树

POJ 2112-Optimal Milking(网络流_最大流+floyd+二分查找)

Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12810   Accepted: 4632 Case Time Limit: 1000MS Description FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 <= C <= 200) co

hdu 1025 Constructing Roads In JGShining&#39;s Kingdom(DP + 二分)

此博客为转发 Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem Description JGShining's kingdom consists of 2n(n is no more than 500,000) small cities which are located in t