• UVA 1025 城市里的间谍 A Spy in the Metro


    城市里的间谍 A Spy in the Metro

    题面翻译

    题目大意

    某城市地铁是一条直线,有 n n n 2 ≤ n ≤ 50 2\leq n\leq 50 2n50)个车站,从左到右编号 1 … n 1\ldots n 1n。有 M 1 M_1 M1 辆列车从第 1 1 1 站开始往右开,还有 M 2 M_2 M2 辆列车从第 n n n 站开始往左开。列车在相邻站台间所需的运行时间是固定的,因为所有列车的运行速度是相同的。在时刻 0 0 0,Mario 从第 1 1 1 站出发,目的在时刻 T T T 0 ≤ T ≤ 200 0\leq T\leq 200 0T200)会见车站 n n n 的一个间谍。在车站等车时容易被抓,所以她决定尽量躲在开动的火车上,让在车站等待的时间尽量短。列车靠站停车时间忽略不计,且 Mario 身手敏捷,即时两辆方向不同的列车在同一时间靠站,Mario 也能完成换乘。

    输入格式

    输入文件包含多组数据。

    每一组数据包含以下 7 7 7 行:

    第一行是一个正整数 n n n,表示有 n n n 个车站。

    第二行是为 T T T,表示 Mario 在时刻 T T T 会见车站 n n n 的间谍。

    第三行有 n − 1 n-1 n1 个整数 t 1 , t 2 , … , t n − 1 t_1,t_2,\ldots,t_{n-1} t1,t2,,tn1,其中 t i t_i ti 表示地铁从车站 i i i i + 1 i+1 i+1 的行驶时间。

    第四行为 M 1 M_1 M1,及从第一站出发向右开的列车数目。

    第五行包含 M 1 M_1 M1 个正整数 a 1 , a 2 , … , a M 1 a_1,a_2,\ldots,a_{M_1} a1,a2,,aM1,即每个列车出发的时间。

    第六行为 M 2 M_2 M2 ,即从第 n n n 站出发向左开的列车数目。

    第七行包含 M 2 M_2 M2 个正整数 b 1 , b 2 , … , b M 2 b_1,b_2,\ldots,b_{M_2} b1,b2,,bM2,即每个列车出发的时间。

    输入文件以一行 0 0 0 结尾。

    输出格式

    有若干行,每行先输出 Case Number XXX : (XXX为情况编号,从 1 1 1 开始),再输出最少等待时间或 impossible(无解)。

    题目描述

    PDF

    分析:

    我们可以用DP~~
    因为要尽可能的让Mario在车站等待的时间短,所以我们要尽量让他在车上呆着。
    我们有一种思路:如果在某个时间点ti,正好有车与Mario所在的车行驶方向相反,并且ti

    在当前这个位置等待;
    转移至从右往左的车上;
    转移至从左往右的车上;
    
    • 1
    • 2
    • 3

    我们可以设f[i][j]为在时间i时处于车站的最大坐车时间。
    于是可以将上面的式子转换为:

    在当前这个位置等待:f[i][j]->f[i+1][j](在j等待)
    转移至从右往左的车上:f[i][j]+t[j]-1->f[i+t[j]-1][j-1]
    转移至从左往右的车上:f[i][j+t[j]]->f[i+t[j]][j+1]
    
    • 1
    • 2
    • 3

    (t[i]表示每相邻两个车站之间需要行驶的时间)
    不懂的看图:
    在这里插入图片描述
    (额······勉强看看吧)

    代码:

    #include
    
    using namespace std;
    
    int n;
    
    int f[10000][10000];
    
    int t;
    
    int s[100000];//从i站到第i+1个站需要的时间 
    
    int m1,m2;
    
    int t1[100000];//向右开的车的发车时间 
    int t2[100000];//向左开的车的发车时间
    
    int ka;
    
    int main()
    {
    	while(cin>>n)
    	{
    		if(n==0)
    		{
    			break;
    		}
    		
    		cin>>t; //输入 
    		
    		for(int i=2;i<=n;i++)
    		{
    			cin>>s[i];
    			
    			s[i]+=s[i-1];
    		}
    		
    		cin>>m1;
    		
    		for(int i=1;i<=m1;i++)
    		{
    			cin>>t1[i];
    		} 
    		
    		cin>>m2;
    		
    		for(int i=1;i<=m2;i++)
    		{
    			cin>>t2[i];
    		} 
    		
    		for(int i=0;i<=t;i++)//开始DP 
    		{
    			for(int j=1;j<=n;j++)
    			{
    				f[i][j]=-1;
    			}
    		} 
    		
    		f[0][1]=0;
    		
    		for(int i=0;i<t;i++)
    		{
    			for(int j=1;j<=n;j++)
    			{
    				if(f[i][j]==-1)
    				{
    					continue;
    				} 
    				
    				f[i+1][j]=max(f[i+1][j],f[i][j]);//在j等待
    				
    				int x=lower_bound(t1+1,t1+m1+1,i-s[j])-t1;//寻找当前时间是否有从左往右开的车正好到站
    				int k=s[j+1]-s[j];
    				
    				if(j^n&&x<=m1&&t1[x]==i-s[j])
    				{
    					f[i+k][j+1]=max(f[i+k][j+1],f[i][j]+k);//刷表法 
    				} 
    				
    				x=lower_bound(t2+1,t2+m2+1,i-(s[n]-s[j]))-t2;//寻找当前时间是否有从右往左开的车正好到站
    				k=s[j]-s[j-1];
    				
    				if(j^1&&x<=m2&&t2[x]==i-(s[n]-s[j]))
    				{
    					f[i+k][j-1]=max(f[i+k][j-1],f[i][j]+k);//刷表法 
    				}
    			}
    		}
    		
    		cout<<"Case Number "<<++ka<<": ";
    		
    		if(f[t][n]!=-1)
    		{
    			cout<<t-f[t][n]<<endl;//有解输出
    		}
    		else
    		{
    			cout<<"impossible"<<endl;//无解
    		}
    	}
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104

    结束啦~~~

  • 相关阅读:
    window 搭建 MQTT 服务器并使用
    【OJ比赛日历】快周末了,不来一场比赛吗? #09.09-09.15 #15场
    电脑重装系统后如何把网站设为首页
    简易绘图 DataFrame.plot
    限制IP到全流程防控,讲解网络爬虫与技术反爬的动态攻防
    论文阅读【2】PreQR: Pre-training Representation for SQL Understanding
    PHP 有趣的函数与功能
    【300+精选大厂面试题持续分享】大数据运维尖刀面试题专栏(一)
    仅需4步,让投资人对你“一见钟情”
    spring实战笔记
  • 原文地址:https://blog.csdn.net/m0_66603329/article/details/126502351