zoukankan      html  css  js  c++  java
  • UVA1025 A Spy in the Metro —— DP

    题目链接: https://vjudge.net/problem/UVA-1025


    题解:

    详情请看紫书P267。 与其说是DP题,我觉得更像是模拟题,特别是用记忆化搜索写。


    递推:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <queue>
    #include <sstream>
    #include <algorithm>
    using namespace std;
    #define pb push_back
    #define mp make_pair
    #define ms(a, b)  memset((a), (b), sizeof(a))
    #define eps 0.0000001
    typedef long long LL;
    const int INF = 2e9;
    const LL LNF = 9e18;
    const int mod = 1e9+7;
    const int maxn = 200+10;
    
    int n, T, M1, M2;
    int t[maxn], has_train[maxn][maxn][2], dp[maxn][maxn];
    int kase = 0;
    
    void init()
    {
        ms(t,0);
        ms(has_train,0);
        ms(dp,0);
    
        scanf("%d",&T);
        for(int i = 1; i<n; i++)
            scanf("%d",&t[i]);
    
        int M1, x;
        scanf("%d",&M1);
        for(int i = 1; i<=M1; i++)
        {
            scanf("%d",&x);
            for(int j = 1; j<=n && x<=T; j++)
            {
                has_train[x][j][0] = 1;
                x += t[j];
            }
        }
    
        int M2;
        scanf("%d",&M2);
        for(int i = 1; i<=M2; i++)
        {
            scanf("%d",&x);
            for(int j = n; j>=1 && x<=T; j--)
            {
                has_train[x][j][1] = 1;
                x += t[j-1];
            }
        }
    }
    
    void solve()
    {
        for(int i = 1; i<=n-1; i++)
            dp[i][j] = INF;
    
        dp[T][n] = 0;
        for(int i = T-1; i>=0; i--)
        for(int j = n; j>=1; 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: ",++kase);
        if(dp[0][1]<INF)
            printf("%d
    ",dp[0][1]);
        else
            puts("impossible");
    }
    
    int main()
    {
        while(scanf("%d",&n) && n)
        {
            init();
            solve();
        }
        return 0;
    }
    


    记忆化搜索:

    #include <iostream>  
    #include <cstdio>  
    #include <cstring>  
    #include <cstdlib>  
    #include <string>  
    #include <vector>  
    #include <map>  
    #include <set>  
    #include <queue>  
    #include <sstream>  
    #include <algorithm>  
    using namespace std;  
    #define pb push_back  
    #define mp make_pair  
    #define ms(a, b)  memset((a), (b), sizeof(a))  
    #define eps 0.0000001  
    typedef long long LL;  
    const int INF = 2e9;  
    const LL LNF = 9e18;  
    const int mod = 1e9+7;  
    const int maxn = 200+10;  
      
    int n, T, M1, M2;  
    int t[maxn], has_train[maxn][maxn][2], dp[maxn][maxn];  
    int kase = 0;  
      
    void init()  
    {  
        ms(t,0);  
        ms(has_train,0);  
        ms(dp,-1);  
      
        scanf("%d",&T);  
        for(int i = 1; i<n; i++)  
            scanf("%d",&t[i]);  
      
        int M1, x;  
        scanf("%d",&M1);  
        for(int i = 1; i<=M1; i++)  
        {  
            scanf("%d",&x);  
            for(int j = 1; j<=n && x<=T; j++)  
            {  
                has_train[x][j][0] = 1;  
                x += t[j];  
            }  
        }  
      
        int M2;  
        scanf("%d",&M2);  
        for(int i = 1; i<=M2; i++)  
        {  
            scanf("%d",&x);  
            for(int j = n; j>=1 && x<=T; j--)  
            {  
                has_train[x][j][1] = 1;  
                x += t[j-1];  
            }  
        }  
      
        for(int i = 1; i<n; i++)  
            dp[T][i] = INF;  
        dp[T][n] = 0;  
    }  
      
    int dfs(int i, int j)  
    {  
        if(dp[i][j]!=-1) return dp[i][j];  
      
        dp[i][j] = dfs(i+1, j) + 1;  
        
        if(j<n && has_train[i][j][0] && i+t[j]<=T)  
            dp[i][j] = min( dp[i][j], dfs( 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], dfs( i+t[j-1], j-1 ) );  
      
        return dp[i][j];  
    }  
      
    int main()  
    {  
        while(scanf("%d",&n) && n)  
        {  
            init();  
            dfs(0,1);  
      
            printf("Case Number %d: ",++kase);  
            if(dp[0][1]<INF)  
                printf("%d
    ",dp[0][1]);  
            else  
                puts("impossible");  
        }  
        return 0;  
    }  
    


  • 相关阅读:
    2018年强化学习领域十篇重要论文(附源码)[转]
    【转载】 再励学习面试真题 (强化学习面试真题)
    枸杞常泡水喝好吗?
    亲历亚马逊、华为机器学习面试,原来考官想听到这些回答[转]
    阿里面试 深度学习[转]
    强化学习(四)用蒙特卡罗法(MC)求解
    初识kaggle,以及记录 kaggle的使用
    强化学习(三)用动态规划(DP)求解
    CORTEX-M3中断的现场保护问题
    地球是圆的怎么还分东西方
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538708.html
Copyright © 2011-2022 走看看