动态规划入门-数字三角形

假设有一组数字三角形,

    2
  6   2
 1  8  4
1 5  6  8

由一个数字可以到下一层的左或右,求一条最短的路径.

使用动态规划

自顶向下考虑,如果要使到达[i,j]最短,则必须选择达到[i-1,j],[i-1,j-1]中较短的一条路径
因此有dp[i][j] = min(dp[i-1][j], dp[i-1][j-1]) + mat[i][j]
dp[1][1]初始化为2

自底向上考虑,dp[i][j]的最短路径应当包含dp[i+1][j]dp[i+1][j+1]的最短路径,因此有dp[i][j] = min(dp[i-1][j], dp[i-1][j-1]) + mat[i][j]

C++代码

#include "bits/stdc++.h"
using namespace std;
#define inf 0x3f3f3f3f

int main(int argc, char const *argv[])
{
    freopen("dp1.txt", "r", stdin);
    /*
        2
      6  2
     1  8  4
    1  5  6  8
    */
    int i,j, n;
    cin >> n;
    int mat[n+1][n+1], dp[n+1][n+1];
    memset(dp, inf, sizeof(dp));
    for(i=1;i<=n;i++){
        for(j=1;j<=i;j++){
            cin >> mat[i][j];
        }
    }
    // 由上向下递推 以最短的路径到达i,j
    //dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - 1]) + mat[i][j]
    dp[1][1] = mat[1][1];
    for(i=2;i<=n;i++){
        for(j=1;j<=i;j++){
            dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - 1]) + mat[i][j];
        }
    }
    /*
          2
        8  4
       9 12 8
     10 14 14 16
    */
    memset(dp, inf, sizeof(dp));
    for(j = 1; j<=n; j++)
        dp[n][j] = mat[n][j];
    //由下向上递推 到达i,j后选择最短的路径
    //dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + mat[i][j];
    for(i=n-1; i>0; i--){
        for(j=1; j<=i; j++){
            dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + mat[i][j];
        }
    }
    /*
            10
          8   12
        2   13  10
      1   5   6   8
    */
    return 0;

}


转载请保留原文链接及作者
本文标题:
文章作者: LepeCoder
发布时间:
原始链接:
原文地址:https://www.cnblogs.com/lepeCoder/p/dp_triangle.html