【疑惑】【玄关】3个小问题
查看原帖
【疑惑】【玄关】3个小问题
766675
da_ke楼主2024/4/4 21:33

代码:

#include <bits/stdc++.h>
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define pii pair<int,int>

using namespace std;

typedef long long ll;
const int N=5e5+24;
const ll INF=1<<29;

int n;
ll d,k;

int dis[N],s[N];
ll dp[N];

bool check(ll g)
{
    rep(i,1,n)
        dp[i]=-INF;
    ll fl=max(d-g,(ll)1), fr=d+g;
    dp[0]=0;
    rep(i,1,n)
        for(int j=i-1;j>=0;j--) // from j to i
        {
            ll d=dis[i]-dis[j];
            if(d<fl)
                continue;
            if(d>fr)
                break;
            dp[i]=max(dp[i],dp[j]+s[i]);
            if(dp[i]>=k)
                return true;
        }
    return false;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("jump.in","r",stdin);
    freopen("jump.out","w",stdout);
#endif
    ios::sync_with_stdio(false);
    cin>>n>>d>>k;
    rep(i,1,n)
        cin>>dis[i]>>s[i];
    int l=0,r=dis[n];
    while(l<r)
    {
        ll mid=l+r>>1;
        if(check(mid))
            r=mid;
        else
            l=mid+1;
    }
    cout<<((l==dis[n])?-1:l);
    // cout<<l;
}

本代码可得\large{\texttt\green{80}}pts.

Q1:for(int j=i-1;j>=0;j--) 中 j>=0 为什么不是 j>=1?

Q2:为什么将 j 的枚举顺序改变只有 50pts?

https://www.luogu.com.cn/record/154308659

50pts 码:

#include <bits/stdc++.h>
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define pii pair<int,int>

using namespace std;

typedef long long ll;
const int N=5e5+24;
const ll INF=1<<29;

int n;
ll d,k;

int dis[N],s[N];
ll dp[N];

bool check(ll g)
{
    rep(i,1,n)
        dp[i]=-INF;
    ll fl=max(d-g,(ll)1), fr=d+g;
    dp[0]=0;
    rep(i,1,n)
        rep(j,0,i-1) // from j to i
        {
            ll d=dis[i]-dis[j];
            if(d>fr)
                continue;
            if(d<fl)
                break;
            dp[i]=max(dp[i],dp[j]+s[i]);
            if(dp[i]>=k)
                return true;
        }
    return false;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("jump.in","r",stdin);
    freopen("jump.out","w",stdout);
#endif
    cin>>n>>d>>k;
    rep(i,1,n)
        cin>>dis[i]>>s[i];
    int l=0,r=dis[n];
    while(l<r)
    {
        ll mid=l+(r-l)/2;
        if(check(mid))
            r=mid;
        else
            l=mid+1;
    }
    cout<<((l==dis[n])?-1:l);
    // cout<<l;
}

Q3:如果不用单调队列,这种算法还可以卡常或优化吗?

2024/4/4 21:33
加载中...