zoukankan      html  css  js  c++  java
  • [CF1201D] Treasure Hunting

    有一个 (n imes m) 的网格,方格上有 (k) 个宝藏,一个人从 ((1,1)) 出发,可以向左或者向右走,但不能向下走。给出 (q) 个列,在这些列上可以向上走,其他列不能向上走。可以重复经过同一个点。求从 ((1,1)) 出发,经过所有宝藏的最短路径长度。(n,m,k,qleq 2 imes 10^5)

    Solution

    (f[i][0/1]) 表示从 ((0,0)) 走到 (i) 行的左侧/右侧,并遍历了 (1 o i-1) 行的所有宝物的最短路径长度

    (挺怕这种题的)

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 500005;
    
    int n,m,k,q,l[N],r[N],f[N][2],b[N],pl[N],pr[N];
    
    int dist(int p,int q) {
        if(p>q) swap(p,q);
        if(pr[p]<=q || pl[q]>=p) return 0;
        return min(pr[q]-q,p-pl[p]);
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>m>>k>>q;
        for(int i=1;i<=n;i++) l[i]=1e9, r[i]=0;
        for(int i=1;i<=k;i++) {
            int t1,t2;
            cin>>t1>>t2;
            l[t1]=min(l[t1],t2);
            r[t1]=max(r[t1],t2);
        }
        for(int i=1;i<=q;i++) {
            int t1;
            cin>>t1;
            b[t1]=1;
        }
        pl[0]=-1e9;
        for(int i=1;i<=m;i++) {
            if(b[i]==1) pl[i]=i;
            else pl[i]=pl[i-1];
        }
        pr[m+1]=1e9;
        for(int i=m;i>=1;--i) {
            if(b[i]==1) pr[i]=i;
            else pr[i]=pr[i+1];
        }
        if(r[1]) f[1][0]=l[1]-1, f[1][1]=r[1]-1;
        else l[1]=1,r[1]=1,f[1][0]=f[1][1]=0;
        int ans=f[1][1];
        for(int i=2;i<=n;i++) {
            if(r[i]==0) {
                f[i][0]=f[i-1][0];
                f[i][1]=f[i-1][1];
                l[i]=l[i-1];
                r[i]=r[i-1];
                ++f[i][0]; ++f[i][1];
                continue;
            }
            f[i][0]=min(f[i-1][0]+2*dist(r[i-1],l[i])+abs(l[i]-r[i-1])+r[i-1]-l[i-1],
                        f[i-1][1]+2*dist(l[i-1],l[i])+abs(l[i]-l[i-1])+r[i-1]-l[i-1]);
            f[i][1]=min(f[i-1][0]+2*dist(r[i-1],r[i])+abs(r[i]-r[i-1])+r[i-1]-l[i-1],
                        f[i-1][1]+2*dist(l[i-1],r[i])+abs(r[i]-l[i-1])+r[i-1]-l[i-1]);
            ++f[i][0]; ++f[i][1];
            //cout<<"i="<<i<<" "<<f[i][0]+r[i-1]-l[i-1]<<" "<<f[i][1]+r[i]-l[i]<<endl;
            ans=min(f[i][0],f[i][1])+r[i]-l[i];
        }
        cout<<ans;
    }
    
    
  • 相关阅读:
    RobotFramework 安装配置(一)
    JAVA练手--集合
    JAVA文件操作
    线性布局--LinearLayout
    android studio导入android studio工程
    通过开机广播(broadcast)通知应用
    Android studio应用导入源码错误This attribute must be localized
    android studio的jni和so
    上传漏洞总结-UPLOAD-LABS
    靶机渗透测试实战(一)——熟悉渗透测试流程的简单测试
  • 原文地址:https://www.cnblogs.com/mollnn/p/12629011.html
Copyright © 2011-2022 走看看