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


原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538708.html