zoukankan      html  css  js  c++  java
  • HDU越狱 DP Or 记忆化搜索

    这题要注意的就是要构造出两个端点出来,然后直接开辟状态dp[i][j]表示i,j之间的囚犯都救出的最少的金币数,注意此时的边界i,j是不取的。初始条件是dp[i][i+1] = 0.

    代码如下:

    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include<iostream>
    using namespace std;
    
    const int inf = 0x3fffffff;
    int N, P, loc[105], dp[105][105];
    
    int dfs(int a, int b)
    {
         if(b - a == 1) return 0;
        if (dp[a][b] ) return dp[a][b];
        int ret = inf;
        for(int c = a+1; c < b; c++){
            ret = min(ret,dfs(a,c)+dfs(c,b)+(loc[b]-loc[a])-2 );    
        }
        dp[a][b] = ret;
        return ret;
    }
    
    int main()
    {
        int T, ca = 1; 
        for (scanf("%d", &T); ca <= T; ++ca) {
            scanf("%d %d", &N, &P);
            loc[0] = 0;
            loc[P+1] = N+1;
            for (int i = 1; i <= P; ++i) {
                scanf("%d", &loc[i]); // 记录囚犯的位置 
            }
            P += 1;
            memset(dp,0,sizeof(dp));
        /*    for(int gap = 2; gap <= P; gap++){
                for(int a = 0; a+gap <= P; a++){
                    int b = a+gap;
                    int ret = inf;
                    for(int c = a+1; c < b; c++){
                        ret = min(ret,dp[a][c]+dp[c][b]+(loc[b]-loc[a]-2));    
                    }    
                    dp[a][b] = ret;
                }    
            }  */
    //        printf("Case #%d: %d\n", ca, dp[0][P]);
            printf("Case #%d: %d\n", ca, dfs(0, P));    
        }
        return 0;    
    }
  • 相关阅读:
    我的暑假周记2018.7.21
    大道至简读后感
    我的暑假周记2018.7.15
    继承与多态
    java联级调用
    古罗马凯撒大帝字串加密
    作业三
    线性同余法产生1000个随机数
    Text2
    java登录界面
  • 原文地址:https://www.cnblogs.com/Lyush/p/2635588.html
Copyright © 2011-2022 走看看