zoukankan      html  css  js  c++  java
  • poj 2353 Ministry 动态规划记忆路径回朔

       设定状态 DP( i, j ) 表示从第一层到 i 层 j 房间 最小花费.

       则状态转移方程为

          DP( i, j ) = Max { DP( i-1,j), DP( i, j-1 ), DP( i, j+1 ) } + a( i , j ) 

       因为 对于当前层的处理, 左右之间可以拆分开来处理,

       再设定一个 d( i, j ) 记忆是由哪个位置走到当前位置的. 然后通过递归求路径即可

    解题代码

    View Code
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    typedef long long LL;
    #define MAX(a,b) (a)>(b)?(a):(b)
    #define MIN(a,b) (a)<(b)?(a):(b)
    const LL inf = 1LL<<60;
    
    LL dp[110][510];
    int a[110][510], d[110][510], n, m;
    
    void GetPath( int r, int c )
    {
        if( r == 0 ){ 
            printf("%d\n", c+1);    
            return;
        }
        int x = d[r][c]/m, y = d[r][c]%m;
        GetPath(x, y);
        printf("%d\n", c+1);
        
    }
    int main()
    {
        while( scanf("%d%d", &n,&m) != EOF)
        {
            for(int i = 0; i < n; i++)
                for(int j = 0; j < m; j++)
                {    
                    scanf("%d", &a[i][j] );
                    dp[i][j] = inf;    
                }    
            for(int i = 0; i < m; i++)
            {
                dp[0][i] = a[0][i];
                d[0][i] = i;
            }
            for(int i = 1; i < n; i++)
            {
                dp[i][0] = dp[i-1][0]+a[i][0];
                d[i][0] = (i-1)*m;    
                for(int j = 1; j < m; j++)
                {
                    if( dp[i][j] > (dp[i-1][j]+a[i][j] ) )
                    {
                        dp[i][j] = dp[i-1][j]+a[i][j];
                        d[i][j] = (i-1)*m + j;    
                    }
                    if( dp[i][j] > (dp[i][j-1]+a[i][j] ) )
                    {
                        dp[i][j] = dp[i][j-1]+a[i][j];
                        d[i][j] = i*m + (j-1);
                    }        
                }
                for(int j = m-2; j >= 0; j-- )
                {
                    if( dp[i][j] > (dp[i][j+1]+a[i][j]) )
                    {
                        dp[i][j] = dp[i][j+1]+a[i][j];
                        d[i][j] = i*m + (j+1);
                    }
                }
            }
            LL Max = inf;
            int res;
    
            for(int i = 0; i < m; i++)
            {    
                if( dp[n-1][i] < Max )
                {
                    Max = dp[n-1][i];
                    res = i;
                }
            }
            GetPath( n-1, res );    
        }
        return 0;
    }
  • 相关阅读:
    [补]2019HDU杭电多校第一场A
    [补]2019nowcoder牛客第三场F(暂且)
    [补]2019nowcoder牛客第一场E、I
    [学]从零(多项式基础与FFT)开始BM学习笔记
    [补]2019nowcoder牛客第二场E、H(upd0730)
    从一个简单的例子对win 服务程序进行讲解
    HTTP协议学习记录及总结
    Windows身份验证与forms身份验证的结合
    关于Sql server 的 几道面试题
    PlaceHolder控件的使用
  • 原文地址:https://www.cnblogs.com/yefeng1627/p/2851939.html
Copyright © 2011-2022 走看看