假设有一组数字三角形,
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;
}