• Uva 1025 A Spy in the Metro


      用dp[i][j]表示i时刻在车站j还需要等待的最小时间。很容易得到边界条件dp[T][n]=0,dp[T][1...n-1]=INF;我们要求的便是dp[0][1].考虑每次的三个决策:

       1)等待1分钟

       2)搭乘向右的车(如果有)

       3)搭乘向左的车(如果有)

    dp[i][j]=max(dp[i+1][j],dp[i+t[i]][j+1],dp[i+t[j-1]][j-1]);    //此处是倒着推的

    /*---dp[i][j]表示i时刻在j站还需要等待的时间
    ----边界条件dp[T][n]=0,dp[T][1...n-1]=INF;
    得到dp[i][j]有如下三种决策:
     1)时刻在j站等待一分钟
     2)搭乘向右的车(如果有)
     3)搭乘向左的车(如果有)
     ---初始化has[i][j][0]表示i时刻在j站是否有向右的车
     ---初始化has[i][j][1]表示i时刻在j站是否有向左的车
    */
    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<vector>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define INF 0x3f3f3f3f
    typedef long long LL;
    const int MAXN = 50 + 10;
    int a[MAXN];
    int b[MAXN];
    int has[200 + 10][MAXN][2];
    int t[MAXN];
    int dp[200 + 10][MAXN];
    int n, m1, m2,T;
    bool vis[200 + 10][MAXN];
    //记忆化搜索
    int dfs(int i, int j){
    	int &ans = dp[i][j];
    	if (vis[i][j])
    		return ans;
    	vis[i][j] = 1;
    	ans = dfs(i + 1, j) + 1;   //等待一分钟
    	if (j<n&&(i + t[j])<= T&&has[i][j][0])
    		ans = min(ans, dfs(i + t[j], j + 1));
    	if (j>1 && i + t[j - 1] <= T&&has[i][j][1])
    		ans = min(ans, dfs(i + t[j - 1], j - 1));
    	return ans;
    }
    int main(){
    	int i, j,iCase=1;
    	while (scanf("%d", &n) && n){
    		scanf("%d", &T);   
    		for (i = 1; i < n; i++)
    			scanf("%d", &t[i]);
    		t[n] = t[0] = 0;
    		scanf("%d", &m1);
    		for (i = 1; i <=m1; i++)
    			scanf("%d", &a[i]);
    		scanf("%d", &m2);
    		for (i = 1; i <= m2; i++)
    			scanf("%d", &b[i]);
    
    		memset(has, 0, sizeof(has));
    
    		for (i = 1; i <= m1; i++){
    			int p = a[i];
    			for (j = 1; j <= n; j++){
    				p += t[j - 1];
    				if (p > T)
    					break;
    				has[p][j][0] = 1;
    			}
    		}
    
    		for (i = 1; i <= m2; i++){
    			int p = b[i];
    			for (j =n; j>0; j--){
    				p += t[j];
    				if (p > T)
    					break;
    				has[p][j][1] = 1;
    			}
    		}
    		memset(dp[T], 0x3f, sizeof(dp[T]));
    		dp[T][n] = 0;
    		memset(vis, 0, sizeof(vis));
    		for (i = 1; i <=n; i++)
    			vis[T][i] = 1;
    		dp[0][1] = dfs(0, 1);
    		printf("Case Number %d: ", iCase++);
    		if (dp[0][1] >= INF)
    			printf("impossible
    ");
    		else
    			printf("%d
    ", dp[0][1]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    《算法竞赛进阶指南》0x00 Hamiton路径 位运算
    HDOJ1170二叉树的遍历 经典问题
    HDOJ1527博弈论之Wythoff游戏
    HDOJ1848NIM博弈 SG函数
    CRC校验码
    Delphi DBGrid 获取焦点几行和几列
    程序进制 常用简写标识
    Delphi 转换函数 HexToBin用法 将16进制字串转成二进制
    细胞-红细胞
    细胞-白细胞-中性粒细胞
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5781745.html
Copyright © 2020-2023  润新知