UVa1025
UVa1025(dp)
紫书的dp入门题目,属于DAG上求最短路径
状态d(i,j)表示i时刻人在车站j的话还需等待的最少时间
对于每种状态有2种决策:
1:无车:等待1分钟
2:有车:搭乘地铁前往最近的一站(左或右选一方向)
数组d的i维需要多开一些,因为d[i + time[j-1]]
可能造成数组溢出引发RE
代码
#include<stdio.h> #include<iostream> #include<algorithm> #define inf 0x3f3f3f3f using namespace std; int main() { int n; int m1, m2; int kase = 0; int t; while (scanf("%d", &n) != EOF&&n) { kase++; int has_train[302][52][2] = { 0 }; int d[302][52] = { 0 }; int time[52] = { 0 }; scanf("%d", &t); for (int i = 1; i < n; i++) { scanf("%d", &time[i]); } scanf("%d", &m1); for (int i = 0; i < m1; i++) { int tem; scanf("%d", &tem); int a = tem; for (int j = 1; j <= n; j++) { has_train[a][j][0] = 1; a += time[j]; } } scanf("%d", &m2); for (int i = 0; i < m2; i++) { int tem; scanf("%d", &tem); int a = tem; for (int j = n; j >= 1; j--) { has_train[a][j][1] = 1; a += time[j - 1]; } } for (int i = 1; i <= n - 1; i++) { d[t][i] = inf; } d[t][n] = 0; for (int i = t - 1; i >= 0; i--) { //d[i][j]表示i时刻,在j站需等的最少时间 for (int j = 1; j <= n; j++) { d[i][j] = d[i + 1][j] + 1; if (j < n&&has_train[i][j][0] && i + time[j] <= t) { d[i][j] = min(d[i][j], d[i + time[j]][j + 1]); } if(j > 1&&has_train[i][j][1]&&i+time[j - 1]<=t){ d[i][j] = min(d[i][j], d[i + time[j - 1]][j - 1]); } } } cout << "Case Number " << kase << ": "; if (d[0][1] >= inf) cout << "impossible\n"; else cout << d[0][1] << "\n"; } }