• 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;  
    }  
    


  • 相关阅读:
    四则运算
    屏蔽恶意IP
    Vue企业级优雅实战05-框架开发01-登录界面
    Vue企业级优雅实战04-组件开发01-SVG图标组件
    Vue企业级优雅实战03-准备工作04-全局设置
    Vue企业级优雅实战02-准备工作03-提交 GIT 平台
    802.11ax TWT
    leetcode338
    春招实习面经(已拿阿里/腾讯/亚马逊)
    leetcode weekly contest138
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538708.html
Copyright © 2020-2023  润新知