Luo Gu [P3957] hopscotch

Title effect: a Given N points and axes, points a little right, starting from the current position 0, can only take the initial distance d, and can stop at any position on the number line, this time, a point will be right with. X is now allowed to pay, so that each can go from a range [max (1, dx), d + x]. It requires at least how much to pay in order to make the point right through and at least k.

Solution: According to the data known of the scope of the problem, the state in (1) the time required state and a one-dimensional O transfers.
If X is found to pay the price to meet the right point and at least K, then pay more costs to meet certain conditions. Thus, consider binary answer, for each half of the cost, a DP, the determination according to the optimal solution, whether or not there passes a point Quanshi point and satisfy the condition.
When dp transfer, the transfer note is the way most continuum value, so consider monotonous queue. First, determine what the new state can be transferred to the current state, the new state into the team; secondly, to determine which state is not legitimate in the squad, which will pop up a queue; and finally a legitimate transfer can be.

code show as below

#include <bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
typedef long long LL;

LL f[maxn];
int n,d,k,pos[maxn],s[maxn];

bool check(int g){
    static int q[maxn];
    int l=1,r=0,now=0;
    for(int i=1;i<=n;i++)f[i]=-1e15;
    for(int i=1;i<=n;i++){
        while(now<i&&pos[i]-pos[now]>=d-g){
            while(l<=r&&f[now]>=f[q[r]])--r;
            q[++r]=now++;
        }
        while(l<=r&&pos[i]-pos[q[l]]>d+g)++l;
        if(l<=r)f[i]=f[q[l]]+s[i];
    }
    for(int i=1;i<=n;i++)if(f[i]>=k)return 1;
    return 0;
}

int main(){
    scanf("%d%d%d",&n,&d,&k);
    LL sum=0;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&pos[i],&s[i]);
        if(s[i]>=0)sum+=s[i];
    }
    if(sum<k)return puts("-1"),0;
    
    int l=0,r=1e9;
    while(l<r){
        int mid=l+r>>1;
        if(check(mid))r=mid;
        else l=mid+1;
    }
    printf("%d\n",l);
    
    return 0;
} 

Guess you like

Origin www.cnblogs.com/wzj-xhjbk/p/11318139.html