• 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
    ",bfs());
    }
  • 相关阅读:
    Entity Framework框架 (一)
    webAPI的常用操作
    图片添加水印和生成验证码
    ASP.NET中Page_Load()与Page_Init()的区别
    session常用操作
    非递归解决组合问题
    TemplateDoesNotExist 异常
    [android]不解锁刷机
    论记忆化搜索
    flex builder 4
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14352751.html
Copyright © 2020-2023  润新知