UVA 1025 A Spy in the Metro (Dynamic Planning)

Keywords: Programming

The example of dynamic programming in Zishu is also Finals in 2003.

What the purple book says is very simple and easy to understand.

To solve this problem, we first need to understand what we can do every second. We can go to the previous station, the next station, or we can wait in situ for a second.

The factors that influence our choice of the scheme are the current time and the station where we are situated.

So these two are the elements we need to constantly adjust. We use dp[i][j] to represent the current first minute and the jth station. We want to stay as little as possible, so each location in our dp records the minimum waiting time in the current situation.

Let's first make dp[T][n] zero, because you have to arrive at station n at exactly the time of T. Then it goes on and on.

Every second is satisfied at a station, dp[i][j] = dp[i + 1][j] + 1. This is equivalent to waiting for one second.

But if there is a subway passing at present, we can choose to go up or not. At this time, we can recursively satisfy DP [i] [j] = min (dp [i] [j], DP [i + T [j] [j + 1]) to the next station or reverse DP [i] [j] = min (dp [i] [j], DP [i - t [j - 1] [j - 1]) to the previous station.

As for how to judge whether there is a subway at the station at the moment, it is very simple.

If it is found that the first station has not been updated, it means that it is impossible to export impossible directly from station 1 to station n within a specified time.

The code is as follows:

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<utility>
#include<stack>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<map>
using namespace std;
const int maxn = 300;
const int INF = 0x3f3f3f3f;

int n, T, m1, m2;
int d1[maxn], d2[maxn], t[maxn];
int dp[maxn][maxn];
bool has_train[maxn][maxn][2];

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
#endif
	int Case = 1;
	while(scanf("%d", &n) != EOF) {
		if(n == 0)
			break;
		memset(has_train, 0, sizeof(has_train));
		memset(dp, 0, sizeof(dp));
		
		scanf("%d", &T);
		for(int i = 1; i < n; i++) {
			scanf("%d", &t[i]);
		}
		scanf("%d", &m1);
		for(int i = 0; i < m1; i++) {
			scanf("%d", &d1[i]);
		}
		scanf("%d", &m2);
		for(int i = 0; i < m2; i++) {
			scanf("%d", &d2[i]);
		}
		
		for(int i = 0; i < m1; i++) {
			int tmp = d1[i];
			for(int j = 1; j <= n; j++) {
				has_train[tmp][j][0] = 1;
				tmp += t[j];
//				if(tmp > T)
//					break;
			}
		}
		
		for(int i = 0; i < m2; i++) {
			int tmp = d2[i];
			for(int j = n; j >= 1; j--) {
				has_train[tmp][j][1] = 1;
				tmp += t[j - 1];
//				if(tmp > T)
//					break;
			}
		}
		for(int i = 1; i <= n - 1; i++)
			dp[T][i] = INF;
		dp[T][n] = 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: ", Case++);
		if(dp[0][1] >= INF)
			printf("impossible\n");
		else
			printf("%d\n", dp[0][1]);
	}
	return 0;
}

Posted by lisaNewbie on Thu, 14 Feb 2019 17:24:18 -0800