D - Jumping Haybales -线段优化坐标DP

24 篇文章 0 订阅
  • D - Jumping Haybales

  •  Gym - 101617D 
  • 题意:
  • 从1,1到n, n求最小步数只是每一秒可以向右或向下走k步若是直接搜索无疑会超时
  • 即便是dp也会超时 只有维护k步内最小值直接进行优化即可,
  • 维护方法有多重选择了简单点的线段树
  • 注意线段树的=的位置,Otherwise, it will RE....
  • 不过线段树也在TLE MLE的边缘
  • #include<bits/stdc++.h>
    using namespace std;
    #define maxn 2111
    #define inf 0x3f3f3f3f
    #define ll int
    ll n,tx,ty;
    int k;
    char mmp[maxn][maxn];
    struct node
    {
        ll l,r,num;
    } L[maxn][maxn*4],R[maxn][maxn*4];
    ll dp[maxn][maxn];
    void creat(node *tree,ll l,ll r,ll root)
    {
        tree[root].l=l;
        tree[root].r=r;
        if(l==r)
        {
            tree[root].num=inf;
            return ;
        }
        ll mid=(l+r)/2;
        creat(tree,mid+1,r,root*2+1);
        creat(tree,l,mid,root*2);
        tree[root].num=min(tree[root*2].num,tree[root*2+1].num);
    }
    void updata(node *tree,ll l,ll ad,ll root)
    {
        if(tree[root].l==l&&tree[root].r==l)
        {
            tree[root].num=ad;
            return ;
        }
        ll mid=(tree[root].l+tree[root].r)/2;
        if(l<=mid)
            updata(tree,l,ad,root*2);
        else
            updata(tree,l,ad,root*2+1);
        tree[root].num=min(tree[root*2].num,tree[root*2+1].num);
    }
    ll query(node *tree,ll l,ll r,ll root)
    {
        if(tree[root].l==l&&tree[root].r==r)
            return tree[root].num;
        ll mid=(tree[root].l+tree[root].r)/2;
        if(l>mid)
            return query(tree,l,r,root*2+1);
        else if(mid>=r)
            return query(tree,l,r,root*2);
        else
            return min(query(tree,l,mid,root*2),query(tree,mid+1,r,root*2+1));
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>n>>k;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                cin>>mmp[i][j];
                dp[i][j]=inf;
            }
        dp[1][1]=0;
        for(int i=1; i<=n; i++)
        {
            creat(L[i],1,n,1);
            creat(R[i],1,n,1);
        }
        updata(L[1],1,0,1);
        updata(R[1],1,0,1);
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                if(i==1&&j==1)
                    continue;
                if(mmp[i][j]=='#')continue;
                dp[i][j]=min(dp[i][j],min(query(L[i],max(1,j-k),j,1),query(R[j],max(1,i-k),i,1))+1);
                if(dp[i][j]!=inf)
                {
                    updata(L[i],j,dp[i][j],1);
                    updata(R[j],i,dp[i][j],1);
                }
            }
        if(dp[n][n]==inf)
            cout<<-1<<endl;
        else
            cout<<dp[n][n]<<endl;
        return 0;
    }
    
  •  
  •  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值