UVA1025 A Spy in the Metro —— DP

来源:互联网 发布:淘宝没有卖热度男装吗 编辑:程序博客网 时间:2024/06/09 17:50

题目链接: 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.0000001typedef 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\n",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\n",dp[0][1]);          else              puts("impossible");      }      return 0;  }  


0 0
原创粉丝点击