UVA - 1025 A Spy in the Metro DP + 分析
2015-06-12 15:49
323 查看
题目大意:有N个车站,M1辆火车从车站1开到车站n,M2辆火车从车站n开到车站1
现在有一个间谍从车站1出发,要求在T时刻的时候和火车站n的另外一名间谍见面
为了不引起怀疑,这个间谍必须将等车时间降到最小
问这个间谍从车站1出发,在T时刻去车站n见另一个间谍的等车时间的最小值
解题思路:这题有两个状态,一个是时间,另一个就是车站了,所以我们设dp[i][j]为在i时刻,j车站的等车时间的最小值
那么就有三种情况了
1.继续等1分钟
2.搭乘往右开的车(如果有)
3.搭乘往左开的车(如果有)
因为要搭车,所以我们要预先处理一下哪个车站哪一时刻有车要开,所以设一个数组has_tarin[i][j][k],表示i时刻,j车站,k方向是否有车要开动,这样就可以得到转移方程了
dp[i][j] = min(dp[i+1][j] + 1, dp[ i+t[j] ][j + 1], dp[i + t[j-1] ][j - 1])
后面两种情况要判断
现在有一个间谍从车站1出发,要求在T时刻的时候和火车站n的另外一名间谍见面
为了不引起怀疑,这个间谍必须将等车时间降到最小
问这个间谍从车站1出发,在T时刻去车站n见另一个间谍的等车时间的最小值
解题思路:这题有两个状态,一个是时间,另一个就是车站了,所以我们设dp[i][j]为在i时刻,j车站的等车时间的最小值
那么就有三种情况了
1.继续等1分钟
2.搭乘往右开的车(如果有)
3.搭乘往左开的车(如果有)
因为要搭车,所以我们要预先处理一下哪个车站哪一时刻有车要开,所以设一个数组has_tarin[i][j][k],表示i时刻,j车站,k方向是否有车要开动,这样就可以得到转移方程了
dp[i][j] = min(dp[i+1][j] + 1, dp[ i+t[j] ][j + 1], dp[i + t[j-1] ][j - 1])
后面两种情况要判断
[code]#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M = 210; const int N = 60; const int INF = 0x3f3f3f3f; int n, T, M1, M2, t , d , e ; int dp[M] , cas = 1; bool has_train[M] [2]; void init() { scanf("%d", &T); for(int i = 1; i <= n - 1; i++) scanf("%d", &t[i]); scanf("%d", &M1); for(int i = 1; i <= M1; i++) scanf("%d", &d[i]); scanf("%d", &M2); for(int i = 1; i <= M2; i++) scanf("%d", &e[i]); memset(has_train, 0, sizeof(has_train)); for(int i = 1; i <= M1; i++) { int tmp = d[i]; has_train[tmp][1][0] = true; for(int j = 1; j <= n - 1; j++) { tmp += t[j]; if(tmp > T) break; has_train[tmp][j+1][0] = true; } } for(int i = 1; i <= M2; i++) { int tmp = e[i]; has_train[tmp] [1] = true; for(int j = n - 1; j >= 1; j--) { tmp += t[j]; if(tmp > T) break; has_train[tmp][j][1] = true; } } } void solve() { for(int i = 1; i <= n - 1; i++) dp[T][i] = INF; dp[T] = 0; for(int i = T - 1; i >= 0; i--) { for(int j = 1; j <= n; j++) { dp[i][j] = dp[i+1][j] + 1; if(j < n && has_train[i][j][0] && i + t[j] <= T) dp[i][j] = min(dp[i][j], dp[i+t[j]][j+1]); if(j > 1 && has_train[i][j][1] && i + t[j-1] <= T) dp[i][j] = min(dp[i][j], dp[i+t[j-1]][j-1]); } } printf("Case Number %d: ", cas++); if(dp[0][1] >= INF) printf("impossible\n"); else printf("%d\n", dp[0][1]); } int main() { while(scanf("%d", &n) != EOF && n) { init(); solve(); } return 0; }
相关文章推荐
- 手把手教你:多表联合更新
- poj_1753
- JAVA中使用JSON进行数据传递
- 10,11,12读书有感
- js函数toFixed 小数保留指定多少位小数
- ByteUtils
- 带宽换算
- db file sequential read 详解
- 2012年12月20日SAT数学每日一题
- 深入浅出FPGA-14-ChipScope软件使用 (深入浅出FPGA系列)
- IOS开发模块总结(一)本地数据存储2 sqlite
- 第三章:MongoDB导出&备份恢复&用户管理
- Java线程详解
- JSP Cookie的创建与读取
- 遍历当前文件目录并且删除所有最近一周没有修改的文件(C/C++)
- Debian修改ssh端口和禁止root远程登陆设置
- php单例模式的两种方法和检测方法
- Groovy&Java multi Map 的引用
- 第二章:MongoDB简单的增删改查
- 学习linux