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";
}
}