zoukankan      html  css  js  c++  java
  • CF1341E Nastya and Unexpected Guest(01dfs)

    这道题需要将它抽象成图论问题,我们用二维数组f表示走到第i个关键点,绿灯还剩j秒的最小回合数,也就是一轮红绿灯

    这样这个问题被抽象成了最短路的问题,因为对于同一个点来说,第一次到达某个状态肯定是最小的,因此能找到最小回合数

    这道题还有一个优化是本题的边权是01的,因此可以用双端队列优化一个log

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    int f[10010][1010];
    int d[N];
    deque<pll> q;
    int main(){
        ios::sync_with_stdio(false);
        int n,m;
        cin>>n>>m;
        int i;
        for(i=1;i<=m;i++){
            cin>>d[i];
        }
        sort(d+1,d+1+m);
        ll ans=1e18;
        int g,r;
        cin>>g>>r;
        memset(f,0x3f,sizeof f);
        f[1][g]=0;
        q.push_front({1,g});
        while(q.size()){
            auto t=q.front();
            int a=t.first;
            int b=t.second;
            q.pop_front();
            if(a>1){
                int dis=d[a]-d[a-1];
                if(b>dis){
                    if(f[a-1][b-dis]>f[a][b]){
                        f[a-1][b-dis]=f[a][b];
                        q.push_front({a-1,b-dis});
                    }
                }
                else if(b==dis){
                    if(f[a-1][g]>f[a][b]+1){
                        f[a-1][g]=f[a][b]+1;
                        q.push_back({a-1,g});
                    }
                }
            }
            if(a<m){
                int dis=d[a+1]-d[a];
                if(b>dis){
                    if(f[a+1][b-dis]>f[a][b]){
                        f[a+1][b-dis]=f[a][b];
                        q.push_front({a+1,b-dis});
                    }
                }
                else if(b==dis){
                    if(f[a+1][g]>f[a][b]+1){
                        f[a+1][g]=f[a][b]+1;
                        q.push_back({a+1,g});
                    }
                }
            }
        }
        for(i=1;i<=m;i++){
            if(n-d[i]<=g&&f[i][g]!=inf){
                ans=min(ans,1ll*(f[i][g])*(g+r)+n-d[i]);
            }
        }
        if(ans==1e18){
            cout<<-1<<endl;
        }
        else{
            cout<<ans<<endl;
        }
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    二叉树(前序,中序,后序遍历)查找
    插入查找
    归并排序
    解密Spring AOP 之AspectJ与动态代理基础知识
    常用的sql
    python 集合方法
    python 字典
    python 列表方法
    python 序列类型
    fake_useragent
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13353391.html
Copyright © 2011-2022 走看看