给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大。
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5

输入格式

第一行包含整数 nn,表示数字三角形的层数。
接下来 nn 行,每行包含若干整数,其中第 ii 行表示数字三角形第 ii 层包含的整数。

输出格式

输出一个整数,表示最大的路径数字和。

数据范围

1≤n≤5001≤n≤500,
−10000≤三角形中的整数≤10000−10000≤三角形中的整数≤10000

输入样例:

5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5

输出样例:

30


  1. //自底向上dp f[i,j]表示从第n层到第i层第j个位置的最大路径和
  2. //f[1,1]
  3. //f[i,j] = max(f[i+1][j],f[i+1][j+1]) + w[i,j];
  4. #include <iostream>
  5. #include <algorithm>
  6. using namespace std;
  7. const int N = 510;
  8. int w[N][N];
  9. int f[N][N];
  10. int n;
  11. int main(){
  12. cin >> n;
  13. for (int i = 1; i <= n; ++i)
  14. for (int j = 1; j <= i; ++j)
  15. cin >> w[i][j];
  16. //最后一列是本身
  17. for (int i = 1; i <= n; ++i) f[n][i] = w[n][i];
  18. for (int i = n-1; i > 0; --i)
  19. for (int j = 1; j <= i; ++j) {
  20. f[i][j] = max(f[i+1][j],f[i+1][j+1]) + w[i][j];
  21. }
  22. cout << f[1][1] << endl;
  23. return 0;
  24. }

写法二

  1. //自底向上dp f[i,j]表示从第n层到第i层第j个位置的最大路径和
  2. //f[1,1]
  3. //f[i,j] = max(f[i+1][j],f[i+1][j+1]) + w[i,j];
  4. #include <iostream>
  5. #include <algorithm>
  6. using namespace std;
  7. const int N = 510;
  8. int f[N][N];
  9. int n;
  10. int main(){
  11. cin >> n;
  12. for (int i = 1; i <= n; ++i)
  13. for (int j = 1; j <= i; ++j)
  14. cin >> f[i][j];
  15. // //最后一列是本身
  16. // for (int i = 1; i <= n; ++i) f[n][i] = w[n][i];
  17. for (int i = n-1; i > 0; --i)
  18. for (int j = 1; j <= i; ++j) {
  19. f[i][j] = max(f[i+1][j],f[i+1][j+1]) + f[i][j];
  20. }
  21. cout << f[1][1] << endl;
  22. return 0;
  23. }