C++跳房子题解

#include<bits/stdc++.h>
using namespace std;
const long long inf=1e10;
int n;
long long d,k;
long long pos[500001],val[500001];
long long dp[500001];
deque<long long> Q;
bool check(long long mid)
{
    if(!Q.empty())Q.clear();
    long long l=(d-mid<0?0:d-mid);
    long long r=d+mid;
    int las=0;
    for(int i=0; i<=n; i++)
        dp[i]=-inf;
    dp[0]=0;
    for(int i=1; i<=n; i++)
    {
        while(pos[las]<pos[i]-r)las++;
        while(pos[i]-l>=pos[las]&&pos[i]-r<=pos[las]&&las<i)
        {
            while(Q.size()&&(dp[Q.back()]<=dp[las]||pos[Q.back()]        <pos[i]-r))
                Q.pop_back();
            Q.push_back(las);
            las++;
        }
        while(Q.size()&&(pos[Q.front()])<pos[i]-r)
            Q.pop_front();
        if(Q.size()!=0)dp[i]=dp[Q.front()]+val[i];
        if(dp[i]>=k)return 1;
    }
    return 0;
}
int main()
{
    scanf("%d%lld%lld",&n,&d,&k);
    for(int i=1; i<=n; i++) scanf("%lld%lld",&pos[i],&val[i]);
    long long l=0,r=pos[n];
    while(l!=r)
    {
        long long mid=(l+r)/2;
        if(check(mid))r=mid;
        else l=mid+1;
    }
    if(!check(l))
    {
        printf("-1");
        return 0;
    }
    else printf("%lld",l);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值