1. 程式人生 > 實用技巧 >CF1341E Nastya and Unexpected Guest(01dfs)

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