当前位置:   article > 正文

经典算法-----数字三角形路径最大问题_数字三角路径

数字三角路径

 目录

前言

问题描述

解决思路

代码实现(C语言)

1.递归算法 

2.递归优化(输出路径)

3.非递归算法(输出路径)


前言

        今天我们接着解决一个问题,也就是求数字三角形路径最大的问题,下面我会详细讲解这个问题的解决思路,以及通过代码的方式去解决这个问题,下面接着看。

问题描述

给出了一个数字三角形,从三角形的顶部到底部有多条不同的路径。 对于每条路径,把路径上面的数加起来可以得到一个和,累加和最大的路径称为“最佳路径”。

样例输入:
第一行是数塔层数N(1<=N<=100)。
第二行起,从一个数字按数塔图形依次递增,共有N层。
5
13
11 8
12 7 26
 6 14 15 8
12 7 13 24 11

最大路径输出结果:86

解决思路

对于这一类问题我们很容易想到去通过递归的方式来解决,先创建一个二维数组来储存这些数据, 然后去通过递归比较大小,取其中比较大的进入到下一层递归,也就是当前节点加上其左边和右边节点较大者。

代码实现(C语言)

1.递归算法 

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. //比较获取最大值
  4. int max(int a, int b) {
  5. return a > b ? a : b;
  6. }
  7. //递归函数
  8. int fun(int n, int i, int j, int** a) {
  9. //如果递归到最上一层的话就直接返回0即可
  10. if (i == n) {
  11. return 0;
  12. }
  13. //进入到递归,当前数字加上左右两边的较大者
  14. return a[i][j] + max(fun(n, i + 1, j, a), fun(n, i + 1, j + 1, a));
  15. }
  16. int main()
  17. {
  18. int n;
  19. printf("enter your num:");
  20. scanf("%d", &n);
  21. //创建二维数组储存数据
  22. int** data = (int**)malloc(sizeof(int*) * n);
  23. for (int i = 0; i < n; i++) {
  24. data[i] = (int*)malloc(sizeof(int) * n);
  25. }
  26. //初始化二维数组为0
  27. for (int i = 0; i < n; i++) {
  28. for (int j = 0; j <= i; j++) {
  29. data[i][j] = 0;
  30. }
  31. }
  32. //输入数据
  33. for (int i = 0; i < n; i++) {
  34. for (int j = 0; j <= i; j++) {
  35. scanf("%d", &data[i][j]);
  36. }
  37. }
  38. //结果
  39. int result= fun(n, 0, 0, data);
  40. printf("最大路径是%d\n", result);
  41. }

结果如下: 

2.递归优化(输出路径)

前面讲到去通过递归的方式来实现这个算法,很明显其时间复杂度为O(2^n),但是如果递归的深度过深的话,也就是说输入的数据很多的话就很容易出现系统计算量过大卡死。对此我们可以通过优化递归的代码来减少时间复杂度,我们可以去创建一个记忆数组来储存前面所递归的结果。举个例子,对于斐波那契数列1 1 2 3 5……,我们可以用递归算法去实现,同样的如果要往很后面算的话也会面临这个问题,如果我们创建这么一个数组array来储存前两个数据的话,到时候我们直接拿出来用就行了比如当前array储存了2和3,那么我要算5的时候就拿出来相加就行了,不需要重新去递归计数2和3了,这时候时间复杂度变为O(n^2)

 既然有了这么一个记忆数组,那么我们还可以去通过这个记忆数组来输出这个路径,代码如下:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. //比较大小
  4. int max(int a, int b) {
  5. return a > b ? a : b;
  6. }
  7. //递归函数,二维数组op是记忆数组,初始化为0,表示没有访问过
  8. int fun(int n, int i, int j, int** a, int** op) {
  9. if (i == n) {
  10. return 0;
  11. }
  12. //如果记忆数组储存了前面的数据,直接返回就行了
  13. if (op[i][j] != 0)
  14. return op[i][j];
  15. op[i][j] = a[i][j] + max(fun(n, i + 1, j, a, op), fun(n, i + 1, j + 1, a, op));
  16. return op[i][j];
  17. }
  18. //打印结果
  19. void print(int result,int**op,int n) {
  20. puts("");//换行
  21. //输出记忆数组op
  22. printf("记忆数组op结果如下:\n");
  23. for (int i = 0; i < n; i++) {
  24. for (int j = 0; j < n; j++) {
  25. printf("%d ", op[i][j]);
  26. }
  27. puts("");
  28. }
  29. printf("最大路径是:%d\n", result);
  30. }
  31. //输出路径
  32. void Find_path(int** op, int** a, int n) {
  33. int j = 0;
  34. printf("路径如下:\n");
  35. printf("%d", a[0][0]);
  36. for (int i = 1; i < n; i++) {
  37. int node = op[i - 1][j] - a[i - 1][j];//减去加上这个位置数字,得到的结果与其左右节对比是否相等
  38. if (node == op[i][j + 1])
  39. j++;
  40. printf("-->%d", a[i][j]);
  41. }
  42. }
  43. int main()
  44. {
  45. int n;
  46. printf("enter your num:");
  47. scanf("%d", &n);
  48. //创建二维数组储存数据
  49. int** data = (int**)malloc(sizeof(int*) * n);
  50. for (int i = 0; i < n; i++) {
  51. data[i] = (int*)malloc(sizeof(int) * n);
  52. }
  53. //初始化二维数组为0
  54. for (int i = 0; i < n; i++) {
  55. for (int j = 0; j <= i; j++) {
  56. data[i][j] = 0;
  57. }
  58. }
  59. //输入数据
  60. for (int i = 0; i < n; i++) {
  61. for (int j = 0; j <=i ; j++) {
  62. scanf("%d", &data[i][j]);
  63. }
  64. }
  65. //op记忆数组
  66. int** op = (int**)malloc(sizeof(int*) * n);
  67. for (int i = 0; i < n; i++) {
  68. op[i] = (int*)malloc(sizeof(int) * n);
  69. }
  70. for (int x = 0; x < n; x++) {
  71. for (int y = 0; y < n; y++)
  72. op[x][y] = 0;//初始化为0,表示未访问
  73. }
  74. int result = fun(n, 0, 0, data,op);
  75. print(result,op,n);
  76. Find_path(op, data, n);
  77. }

结果如下:

3.非递归算法(输出路径)

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. int max(int a, int b) {
  5. return a > b ? a : b;
  6. }
  7. //非递归算法函数
  8. void find(int n, int** a, int** op) {
  9. for (int j = 0, i = n - 1; j < n; j++) {
  10. op[i][j] = a[i][j];//先把最后一次数据放入到记忆数组op中
  11. }
  12. for (int x = n - 2; x >= 0; x--) {
  13. for (int y = 0; y <= x; y++) {
  14. int temp = max(op[x + 1][y], op[x + 1][y + 1]);
  15. op[x][y] = temp + a[x][y];
  16. }
  17. }
  18. }
  19. //获取路径储存到path数组当中
  20. void find_path(int n, int* path, int** op, int** a) {
  21. path[0] = a[0][0];
  22. int j = 0;
  23. for (int i = 1; i < n; i++)
  24. {
  25. int node = op[i - 1][j] - a[i - 1][j];
  26. if (node == op[i][j + 1])
  27. j++;
  28. path[i] = a[i][j];
  29. }
  30. }
  31. //输出结果
  32. void print(int* path, int n, int** op) {
  33. printf("记忆数组op结果如下:\n");
  34. for (int i = 0; i < n; i++) {
  35. for (int j = 0; j < n; j++)
  36. printf("%d ", op[i][j]);
  37. printf("\n");
  38. }
  39. printf("路径如下:\n");
  40. for (int i = 0; i < n; i++)
  41. printf("%d-->", path[i]);
  42. printf("end\n");
  43. printf("最大路径是:%d\n", op[0][0]);
  44. }
  45. int main()
  46. {
  47. int n;
  48. printf("enter your num:");
  49. scanf("%d", &n);
  50. //创建二维数组储存数据
  51. int** data = (int**)malloc(sizeof(int*) * n);
  52. for (int i = 0; i < n; i++) {
  53. data[i] = (int*)malloc(sizeof(int) * n);
  54. }
  55. //初始化二维数组为0
  56. for (int i = 0; i < n; i++) {
  57. for (int j = 0; j <= i; j++) {
  58. data[i][j] = 0;
  59. }
  60. }
  61. //输入数据
  62. for (int i = 0; i < n; i++) {
  63. for (int j = 0; j <=i ; j++) {
  64. scanf("%d", &data[i][j]);
  65. }
  66. }
  67. //op
  68. int** op = (int**)malloc(sizeof(int*) * n);
  69. for (int i = 0; i < n; i++) {
  70. op[i] = (int*)malloc(sizeof(int) * n);
  71. }
  72. for (int x = 0; x < n; x++) {
  73. for (int y = 0; y < n; y++)
  74. op[x][y] = 0;
  75. }
  76. //储存路径数组path
  77. int* path = (int*)malloc(sizeof(int) * n);
  78. memset(path, 0, sizeof(path));//初始化
  79. find(n, data, op);
  80. find_path(n, path, op, data);
  81. print(path,n,op);
  82. }

结果如下:

以上就是本期的全部内容了,我们下一次见!

分享一张壁纸:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/551266
推荐阅读
相关标签
  

闽ICP备14008679号