1340C.Nastya and Unexpected Guest(最短路+dp+01BFS优化)
题意:
一条路长度为n
从0出发,有m个站点
绿灯红灯交替变换
绿灯的时候必须走
从一个站点出来后方向不能变
红灯的时候必须站在一个站点上
求最短多少时间可以到达n点
题解:
定义f(i,j)为到第i个站点时,绿灯当前时间为j,经过了最少轮数红绿灯变色
那么f(i,j)可以往后转移
f(i−1,j+x) f(i+1,j+y) f(i,0)
根据题意写转移即可。
这个转移方程要求的是最少轮数,所以就是一个广义的最短路模型。但是这题直接跑nlogm的最短路是会被卡掉的。
这里介绍一种基于01图的最短路求解方法,用双端队列代替优先队列做一个01BFS,时间复杂度是O(n+m)。
//定义f(i,j)为到第i个站点时,绿灯当前时间为j,经过了最少轮数红绿灯变色 //那么f(i,j)可以往后转移 //f(i-1,j+x) f(i+1,j+y) f(i-1,0) f(i+1,0) #include<bits/stdc++.h> using namespace std; int n,m,g,r; int f[10100][1010]; int vis[10100][1010]; int a[10100]; struct qnode { int x; int y; qnode (int xx,int yy) { x=xx; y=yy; } }; long long bfs () { deque<qnode> q; q.push_back(qnode(0,0)); vis[0][0]=1; long long ans=1e18; while (q.size()) { qnode tt=q.front(); q.pop_front(); if (tt.y==0) { //如果当前绿灯时间刚刚开始 //看看能不能直接走到终点 int t1=n-a[tt.x]; if (t1<=g) { long long tmp=1ll*f[tt.x][tt.y]*(g+r)+t1; ans=min(ans,tmp); } } if (tt.y==g) { if (!vis[tt.x][0]) { f[tt.x][0]=f[tt.x][tt.y]+1; vis[tt.x][0]=1; q.push_back(qnode(tt.x,0)); } continue; } if (tt.x>1) { //如果不在1号点 //可以往回走 int x=tt.x-1; int y=tt.y+a[tt.x]-a[x]; if (y<=g&&!vis[x][y]) { vis[x][y]=1; f[x][y]=f[tt.x][tt.y]; q.push_front(qnode(x,y)); } } if (tt.x<m) { //如果不在m号点 //可以往后走 int x=tt.x+1; int y=tt.y+a[x]-a[tt.x]; if (y<=g&&!vis[x][y]) { vis[x][y]=1; f[x][y]=f[tt.x][tt.y]; q.push_front(qnode(x,y)); } } } if (ans==1e18) ans=-1; return ans; } int main () { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) scanf("%d",a+i); scanf("%d%d",&g,&r); sort(a+1,a+m+1); printf("%lld\n",bfs()); }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· C# 13 中的新增功能实操
· Ollama本地部署大模型总结
· 2025成都.NET开发者Connect圆满结束
· langchain0.3教程:从0到1打造一个智能聊天机器人
· 用一种新的分类方法梳理设计模式的脉络