传送门

参考资料:

  [1]:算法竞赛入门经典:第九章 DAG上的动态规划

题意:

  Algorithm城市的地铁有 n 个站台,编号为 1~n,共有 M1+M2 辆列车驶过;

  其中 M1 辆列车从 1 号站台驶向 n 号站台,M2 辆列车从 n 号站台驶向 1 号地铁;

  (单程线,M1 辆列车到达 n 号站台后不会回返,同理 M2)

  特工 Maria 要在 T 时刻到达 n 号站台与特务会面,但为了保证安全,在会面前尽量呆在行进的列车中;

  现给出你这 M1+M2 辆列车的发车时刻;

  问如何换乘列车使得特工 Maria 能在 T 时刻前到达 n 号站台,并且在换乘期间在站台的停留时间最短;

  如果可以在规定时间到达 n 站台,输出在站台停留的最短时间,反之,输出 "impossible";

题解:

  看完书上的解释后,感觉,不像是DAG上的动态规划,倒有点像背包的味道;

 int n,t;
int m1,m2;
int f[maxn];///前m1辆列车的发车时刻
int e[maxn];///后m2辆列车的发车时刻
int c[maxn];///c[i]:车站i到车站i+1的时间花费
/**
(i,j):i时刻在车站j
dp[i][j]:从(i,j)->(t,n)所需等待的最少时间
*/
int dp[maxn][];
/**
hasTrain[i][j][0]=true:i时刻在车站j有到j+1的火车
hasTrain[i][j][1]=true:i时刻在车站j有到j-1的火车
*/
bool hasTrain[maxn][][];

  最关键的便是dp[ i ][ j ]的定义;

  之所以定义成二维的,是因为决策受当前时间和所处车站的影响,有两个影响因素;

  定义好后,便是找状态转移方程了;

  首先预处理出 hasTrain 数组:

 void Init()///预处理hasTrain
{
mem(hasTrain,false);
for(int i=;i <= m1;++i)
{
int cnt=f[i];
hasTrain[cnt][][]=true;
for(int j=;j <= n;++j)
{
cnt += c[j-];
hasTrain[cnt][j][]=true;
}
}
for(int i=;i <= m2;++i)
{
int cnt=e[i];
hasTrain[cnt][n][]=true;
for(int j=n-;j >= ;--j)
{
cnt += c[j];
hasTrain[cnt][j][]=true;
}
}
}

预处理hasTrain[]

  令dp[t][n]=0,dp[t][1,2,...,n-1]=INF;

  按照时间逆序遍历,对于状态 dp[ i ][ j ]:

  ①等一分钟,下一分钟从车站 j 出发到达(t , n);

  ②搭乘往右开的列车;

  ③搭乘往左开的列车;

  

AC代码:

 #include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=+; int n,t;
int m1,m2;
int f[maxn];///前m1辆列车的发车时刻
int e[maxn];///后m2辆列车的发车时刻
int c[maxn];///c[i]:车站i到车站i+1的时间花费
/**
(i,j):i时刻在车站j
dp[i][j]:从(i,j)->(t,n)所需等待的最少时间
*/
int dp[maxn][];
/**
hasTrain[i][j][0]=true:i时刻在车站j有到j+1的火车
hasTrain[i][j][1]=true:i时刻在车站j有到j-1的火车
*/
bool hasTrain[maxn][][]; void Init()///预处理hasTrain
{
mem(hasTrain,false);
for(int i=;i <= m1;++i)
{
int cnt=f[i];
hasTrain[cnt][][]=true;
for(int j=;j <= n;++j)
{
cnt += c[j-];
hasTrain[cnt][j][]=true;
}
}
for(int i=;i <= m2;++i)
{
int cnt=e[i];
hasTrain[cnt][n][]=true;
for(int j=n-;j >= ;--j)
{
cnt += c[j];
hasTrain[cnt][j][]=true;
}
}
}
void Solve()
{
Init();
for(int i=;i < n;++i)
dp[t][i]=INF;
dp[t][n]=;
for(int i=t-;i >= ;--i)
{
for(int j=;j <= n;++j)
{
dp[i][j]=dp[i+][j]+;
if(j < n && hasTrain[i][j][] && i+c[j] <= t)
dp[i][j]=min(dp[i][j],dp[i+c[j]][j+]);
if(j > && hasTrain[i][j][] && i+c[j-] <= t)
dp[i][j]=min(dp[i][j],dp[i+c[j-]][j-]);
}
}
if(dp[][] >= INF)
puts("impossible");
else
printf("%d\n",dp[][]);
}
int main()
{
int kase=;
while(~scanf("%d",&n) && n)
{
scanf("%d",&t);
for(int i=;i < n;++i)
scanf("%d",c+i);
scanf("%d",&m1);
for(int i=;i <= m1;++i)
scanf("%d",f+i);
scanf("%d",&m2);
for(int i=;i <= m2;++i)
scanf("%d",e+i); printf("Case Number %d: ",++kase);
Solve();
}
return ;
}

UVA 1025 "A Spy in the Metro " (DAG上的动态规划?? or 背包问题??)的更多相关文章

  1. UVA - 1025 A Spy in the Metro[DP DAG]

    UVA - 1025 A Spy in the Metro Secret agent Maria was sent to Algorithms City to carry out an especia ...

  2. UVA 1025 -- A Spy in the Metro (DP)

     UVA 1025 -- A Spy in the Metro  题意:  一个间谍要从第一个车站到第n个车站去会见另一个,在是期间有n个车站,有来回的车站,让你在时间T内时到达n,并且等车时间最短, ...

  3. uva 1025 A Spy in the Metro 解题报告

    A Spy in the Metro Time Limit: 3000MS     64bit IO Format: %lld & %llu Submit Status uDebug Secr ...

  4. UVA 437 The Tower of Babylon(DAG上的动态规划)

    题目大意是根据所给的有无限多个的n种立方体,求其所堆砌成的塔最大高度. 方法1,建图求解,可以把问题转化成求DAG上的最长路问题 #include <cstdio> #include &l ...

  5. UVA 1025 A Spy in the Metro 【DAG上DP/逆推/三维标记数组+二维状态数组】

    Secret agent Maria was sent to Algorithms City to carry out an especially dangerous mission. After s ...

  6. DAG的动态规划 (UVA 1025 A Spy in the Metro)

    第一遍,刘汝佳提示+题解:回头再看!!! POINT: dp[time][sta]; 在time时刻在车站sta还需要最少等待多长时间: 终点的状态很确定必然是的 dp[T][N] = 0 ---即在 ...

  7. UVa 1025 A Spy in the Metro(动态规划)

    传送门 Description Secret agent Maria was sent to Algorithms City to carry out an especially dangerous ...

  8. uva 1025 A Spy int the Metro

    https://vjudge.net/problem/UVA-1025 看见spy忍俊不禁的想起省赛时不知道spy啥意思 ( >_< f[i][j]表示i时刻处于j站所需的最少等待时间,有 ...

  9. UVa 1025 A Spy in the Metro

    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=35913 预处理出每个时间.每个车站是否有火车 为了方便判断是否可行,倒推处理 ...

随机推荐

  1. 页面滚动事件和利用JS实现回到顶部效果

    页面滚动 事件:window.onscroll, 获得页面滚动位置:document.body.scrollTop: HTML代码: 这里注意此处逻辑,大于500就显示,否则就隐藏,还有注意如果变量名 ...

  2. date、cal和clear命令

    一.date命令 date命令的功能:date命令是显示或设置系统时间与日期. 很多shell脚本里面需要打印不同格式的时间或日期,以及要根据时间和日期执行操作.延时通常用于脚本执行过程中提供一段等待 ...

  3. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十一章:环境光遮蔽(AMBIENT OCCLUSION)

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十一章:环境光遮蔽(AMBIENT OCCLUSION) 学习目标 ...

  4. appium处理混合APP_获取上下文(切换句柄)

    //混合APP的处理 //getContextHandles():获取所有可用的上下文//context():设置上下文//getContext():获取当前上下文 //1. getContext() ...

  5. Python中的动态继承

    所谓动态继承,是指代码运行时再决定某个类的父类.某些场景下会用到,比如threading.Thread和multiprocessing.Process这两个类有很多同名的接口,可以实现某个子类动态继承 ...

  6. 洛谷1602 Sramoc问题

      刚看到这道题的时候感觉像spfa. 然后发现其实bfs就可以做了. //Serene #include<algorithm> #include<iostream> #inc ...

  7. MacOS利用Terminal访问远程Linux服务器

    常用命令 默认22端口访问 ssh x.x.x.x 指定端口访问 ssh x.x.x.x -p port 指定用户访问(默认是MacOS当前用户) ssh user@x.x.x.x [-p port] ...

  8. 正则表达式问题:如何理解/href\s*=\s*(?:"(?<1>[^"]*)"|(?<1>\S+))/(转载)

    ms-help://MS.VSCC/MS.MSDNVS.2052/jscript7/html/jsjsgrpregexpsyntax.htm 该文虽有解释, 但没有样例,对我这样的初学者来说很难理解 ...

  9. QT_OPENGL-------- 5.model

    在qt中实现opengl obj模型导入: main.cpp #include<GL/glew.h> #include <GLFW/glfw3.h> #include<s ...

  10. MaxCompute 图计算用户手册(下)

    示例程序 强连通分量 在有向图中,如果从任意一个顶点出发,都能通过图中的边到达图中的每一个顶点,则称之为强连通图.一张有向图的顶点数极大的强连通子图称为强连通分量.此算法示例基于 parallel C ...