SSL_2852&&P3957【跳房子】

跳房子

题目

P3957


解析

显而易见,首先二分答案,每次裸DP一下,求上下界即可
因为裸DP是O(n2)的,再加个log,2s时限+氧气也救不回来
考虑优化DP,显而易见单调队列,注意这里踢的条件以x的差值为界限
快读快输已成日常

code:

#include<cstring>
#include<cstdio>
#define int long long
using namespace std;
inline int max(int x,int y){
    
    }
inline bool idigit(char x){
    
    return (x<'0'|x>'9')?0:1;}
inline int read()
{
    
    
	int num=0,f=1;
	char c=0;
	while(!idigit(c=getchar())){
    
    if(c=='-')f=-1;}
	while(idigit(c))num=(num<<1)+(num<<3)+(c&15),c=getchar();
	return num*f;
}
inline void write(int x)
{
    
    
	int F[20];
	int tmp=x>0?x:-x;
	if(x<0)putchar('-');
	int cnt=0;
	while(tmp>0){
    
    F[cnt++]=tmp%10+'0';tmp/=10;}
	while(cnt>0)putchar(F[--cnt]);
	if(x==0)putchar('0');
	putchar('\n');
}
int n,d,g,dp[500010],p,q,L=0,R,mid,x[500010],ans=1e18,s[500010],la,b[500010],l,r;
bool check(int y)
{
    
    
	p=max(d-y,1),q=d+y,la=1,l=1,r=1,b[1]=0;
	for(int i=1;i<=n;++i)
	{
    
    
		while(l<r&&x[i]-x[b[l]]>q)++l;
		if(x[i]-x[b[l]]<=q&&x[i]-x[b[l]]>=p){
    
    dp[i]=dp[b[l]]+s[i];if(dp[i]>=g)return 1;}
		else dp[i]=-4e17;
		while(la<=i&&x[i+1]-x[la]>=p)
		{
    
    
			while(l<=r&&dp[b[r]]<=dp[la])--r;
			b[++r]=la,++la;
		}
	}
	return 0;
}
signed main()
{
    
    
	n=read(),d=read(),g=read();
	for(int i=1;i<=n;++i)x[i]=read(),s[i]=read();
	R=1e9;
	while(L<=R)
	{
    
    
		mid=(L+R)>>1;
		if(check(mid))R=mid-1,ans=(ans>mid)?mid:ans;
		else L=mid+1;
	}//注意二分条件,保证ans是可行解
	if(ans==1e18)printf("-1");
	else write(ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zhanglili1597895/article/details/114433275