UVa1025 - A Spy in the Metro

        紫书DP第一道例题,实力不够,刷不动exercises,只能来刷examples。首先找出“状态”,根据状态来DP。dp[i][j],i表示当前时间,j表示车站号,数组存还需要等待的最短时间。然后分析决策种类,共有三种,等待一分钟,搭乘正方向的车,搭乘反方向的车,逆向DP,在三种决策中选出最优。DP前预处理好在某个时间某个车站是否有车。


#include <iostream>  
#include <stdio.h>  
#include <cmath>  
#include <algorithm>  
#include <iomanip>  
#include <cstdlib>  
#include <string>  
#include <memory.h>  
#include <vector>  
#include <queue>  
#include <stack>  
#include <map>
#include <ctype.h>  
#define INF 1000000

using namespace std;

int t[60];//相邻两站时间 
int d[60];//M1
int e[60];//M2
bool dd[350][60];
bool ee[350][60];
int dp[350][60];

int main(){
	int N;//车站数  max 50
	int T;//约定时间 max200
	int M1;//从第一个站发的车
	int M2;//从最后一个站发的车 
	int _case=0;
	while(cin>>N){
		if(!N)break;
		cin>>T;
		
		t[0]=t[N]=0;
		for(int i=1;i<N;i++)cin>>t[i];
		cin>>M1;
		for(int i=1;i<=M1;i++)cin>>d[i];
		cin>>M2;
		for(int i=1;i<=M2;i++)cin>>e[i];
		
		//init 
		for(int i=0;i<350;i++){
			for(int j=0;j<60;j++)dp[i][j]=INF;
		}
		dp[T][N]=0;
		memset(dd,0,sizeof(dd));memset(ee,0,sizeof(ee));
		for(int i=1;i<=M1;i++){
			int tmp=0;
			for(int j=1;j<N;j++){
				tmp+=t[j-1];
				dd[d[i]+tmp][j]=true;
			}
		}
		for(int i=1;i<=M2;i++){
			int tmp=0;
			for(int j=N;j>1;j--){
				tmp+=t[j];
				ee[e[i]+tmp][j]=true;
			}
		}
		
		for(int i=T-1;i>=0;i--){
			for(int j=N;j>=1;j--){
				int tmp=INF;
				//向右开 
				if(j<N&&dd[i][j]&&dp[i+t[j]][j+1]!=INF){
					tmp=min(tmp,dp[i+t[j]][j+1]);
				}
				//向左
				if(j>1&&ee[i][j]&&dp[i+t[j-1]][j-1]!=INF){
					tmp=min(tmp,dp[i+t[j-1]][j-1]);
				}
				//等 
				if(dp[i+1][j]!=INF)tmp=min(tmp,dp[i+1][j]+1);
				dp[i][j]=tmp;
			}
		}
		_case++;
		cout<<"Case Number "<<_case<<": ";
		if(dp[0][1]!=INF){
			cout<<dp[0][1]<<endl;
		}else{
			cout<<"impossible"<<endl;
		}
	}
	
	return 0;
}


你可能感兴趣的:(dp,uva)