hdu 6071 Lazy Running
题
OvO http://acm.hdu.edu.cn/showproblem.php?pid=6071
2017 Multi-University Training Contest - Team 4 - 1005
解
因为能在2,3之间来回走,所以如果能走T,那么一定能走T+2t(dis[2][3]) (t为自然数)
然后就可以用类似记忆化搜索的方法做
用vis[i][j]表示到达i,走的距离对2*dis[2][3]取模,这个状态是否存在。
(思路来自题解之类的地方)
#include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <cstdio> #include <queue> using namespace std; typedef long long ll; struct node { int now; ll d,dmod; friend bool operator<(node x,node y) { return x.dmod > y.dmod; } }; int mod; priority_queue<node> que; ll k,dis[5][5]; bool vis[5][60044]; int nxt(int now,int chg){ return ((now+chg-1+4)%4+1); } void solve() { int i,j,u,v; node q,tmp; mod=dis[2][3]*2; ll ans=((k-1)/mod*mod+mod); memset(vis,0,sizeof(vis)); while(!que.empty()) que.pop(); vis[2][0]=1; q.now=2; q.d=q.dmod=0; que.push(q); while(!que.empty()) { q=que.top(); que.pop(); if(q.d>ans) break; u=q.now; for(i=-1;i<=1;i+=2) { v=nxt(u,i); tmp=q; tmp.now=v; tmp.d+=(dis[u][v]); tmp.dmod=tmp.d%mod; if(tmp.d>=k && tmp.now==2) { ans=min(ans,tmp.d); continue; } if(vis[v][tmp.dmod]) continue; vis[v][tmp.dmod]=1; if(tmp.d>k) tmp.dmod=tmp.d; que.push(tmp); } } ll kmod=k%mod; for(i=0;i<mod;i++) if(vis[2][i]) ans=min(ans,((k-i-1)/mod+1)*mod+i); printf("%lld\n",ans); } int main() { int cas,i,j,a,b; cin>>cas; while(cas--) { scanf("%lld",&k); for(i=1;i<=4;i++) { a=i; b=nxt(i,1); scanf("%d",&dis[a][b]); dis[b][a]=dis[a][b]; } solve(); } return 0; }