【uva 1025】A Spy in the Metro

【题目链接】:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3466

【题意】

有n个站台;(线性的);
每相邻两个站台之间的火车的行驶时间是固定的;
然后每天在第一个站台会向第n个站台的方向发出m1辆车;
最后一个站台会向第1个站台的方向发出m2辆车;
给出m1辆车是何时发出的,m2辆车是何时发出的(递增顺序给出);
然后有一个人要从1号站台,到n号站台;
且要求在T时刻会面;
可以在站台上等待;
问你它最少需要在站台上等待的时间;(在车上就不占时间);

【题解】

设dp[i][j]表示在第i时刻,在第j个站台所需的最短等待时间;
dp[0][1] = 0,dp[0][2..n]=INF;
在每一个站台有3种可能的决策
1.站在站台不动,时间递增1,站台不变;
2.搭上某一辆车;(向左或向右),时间不变,站台改变;
则有
dp[i][j]=dp[i1][j]+1;
dp[i][j]=min(dp[i][j],dp[it[j]][j+1])
(it[j],j+1);
dp[i][j]=min(dp[i][j],dp[it[j1]][j1])
(it[j],j1);
在何时在某一站有向左/向右的车可以在读时间的时候就预处理出来;
注意超过T就结束->注意break和continue;
这样DP数组的第一维最大为T,第二维最大为N
最后输出dp[T][n];
当然要判断一下是否有解

【Number Of WA

3

【反思】

在break和continue的使用上竟然还会出现问题。
Case那个东西要记得输出。

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define Open() freopen("F:\\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 50;
const int MAXT = 200;
const int INF = 0x3f3f3f3f;

int n,T,t[N+10],has[200+10][N+10][2];
int m,dp[MAXT+10][N+10];

int main(){
    //Open();
    //Close();
    int kk = 0;
    while (~scanf("%d",&n)){
        if (n==0) break;
        kk++;
        ms(has,0),ms(dp,INF);
        scanf("%d",&T);
        rep1(i,1,n-1)
            scanf("%d",&t[i]);
        scanf("%d",&m);
        rep1(i,1,m){
            int now;scanf("%d",&now);
            if (now>T) continue;
            has[now][1][0] = 1;
            rep1(j,1,n-1){
                now+=t[j];
                if (now>T) break;
                has[now][j+1][0] = 1;
            }
        }
        scanf("%d",&m);
        rep1(i,1,m){
            int now;scanf("%d",&now);
            if (now>T) continue;
            has[now][n][1] = 1;
            rep2(j,n-1,1){
                now+=t[j];
                if (now>T) break;
                has[now][j][1] = 1;
            }
        }
        dp[0][1] = 0;
        rep1(i,2,n) dp[0][i] = INF;
        rep1(i,1,T)
            rep1(j,1,n){
                dp[i][j] = dp[i-1][j] + 1;
                if (j+1<=n && i-t[j]>=0 && has[i-t[j]][j+1][1]) // <-
                    dp[i][j] = min(dp[i][j],dp[i-t[j]][j+1]);
                if (j-1>=1 && i-t[j-1]>=0 && has[i-t[j-1]][j-1][0]) // ->
                    dp[i][j] = min(dp[i][j],dp[i-t[j-1]][j-1]);
            }
        cout << "Case Number "<<kk<<": ";
        if (dp[T][n]>=INF)
            cout <<"impossible"<<endl;
        else
            cout << dp[T][n] << endl;
    }
    return 0;
}
posted @ 2017-10-04 18:44  AWCXV  阅读(83)  评论(0编辑  收藏  举报