zoukankan      html  css  js  c++  java
  • 数字三角形从顶到底的最大路径和

    问题描述:

               7

           3       8

       8       1        0

    2      7       4          4

          在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或右下走。只需要求出这个最大和即可,不必给出具体路径。

          三角形的行数大于1小于等于100,数字为0~99.

    输入格式:

    4 ///三角形的行数。下面是三角形

    7

    3 8

    8 1 0

    2 7 4 4

    要求输出最大和

    第一种方法:利用递归(超时,原因是重复计算,时间复杂度是2n

     1 #include <iostream>
     2 #include <algorithm>
     3 #define Max 101
     4 using namespace std;
     5 int D[Max][Max];
     6 int n;
     7 int MaxSum(int i,int j)
     8 {
     9     if(i==n)
    10         return D[i][j];
    11     int x=MaxSum(i+1,j);
    12     int y=MaxSum(i+1,j+1);
    13     return max(x,y)+D[i][j];
    14 }
    15 int main()
    16 {
    17     int i,j;
    18     cin>>n;
    19     for(i=1;i<=n;i++)
    20         for(j=1;j<=i;j++)
    21     {
    22         cin>>D[i][j];
    23     }
    24     cout<<MaxSum(1,1)<<endl;
    25     return 0;
    26 }

    第二种方法是动态规划(用数组存放已经计算出来的值,避免重复计算,时间复杂度是n2

     1 #include <iostream>
     2 #include <algorithm>
     3 using namespace std;
     4 #define Max 101
     5 int D[Max][Max];
     6 int n;
     7 int maxSum[Max][Max];
     8 int MaxSum(int i,int j)
     9 {
    10     if(maxSum[i][j]!=-1)
    11         return maxSum[i][j];
    12     if(i==n)
    13         maxSum[i][j]=D[i][j];
    14     else
    15     {
    16         int x=MaxSum(i+1,j);
    17         int y=MaxSum(i+1,j+1);
    18         maxSum[i][j]=max(x,y)+D[i][j];
    19     }
    20     return maxSum[i][j];
    21 }
    22 int main()
    23 {
    24     int i,j;
    25     cin>>n;
    26     for(i=1;i<=n;i++)
    27         for(j=1;j<=i;j++)
    28     {
    29         cin>>D[i][j];
    30         maxSum[i][j]=-1;
    31     }
    32     cout<<MaxSum(1,1)<<endl;
    33     return 0;
    34 }

     第三种方法:递归改为递推,从底往上计算

     1 #include <iostream>
     2 #include <algorithm>
     3 using namespace std;
     4 #define Max 101
     5 int D[Max][Max];
     6 int n;
     7 int maxSum[Max][Max];
     8 int main()
     9 {
    10     int i,j;
    11     cin>>n;
    12     for(i=1;i<=n;i++)
    13     {
    14         for(j=1;j<=i;j++)
    15             cin>>D[i][j];
    16     }
    17     for(int i=1;i<=n;i++)
    18         maxSum[n][i]=D[n][i];
    19     for(int i=n-1;i>=1;i--)
    20         for(int j=1;j<=i;j++)
    21     {
    22         maxSum[i][j]=max(maxSum[i+1][j],maxSum[i+1][j+1])+D[i][j];
    23     }
    24     cout<<maxSum[1][1]<<endl;
    25     return 0;
    26 }

    第四种方法:进行空间优化 将二维数组转变为一维数组向上翻滚

     1 #include <iostream>
     2 #include <algorithm>
     3 using namespace std;
     4 #define Max 101
     5 int D[Max][Max];
     6 int n;
     7 int *maxSum;
     8 int main()
     9 {
    10     int i,j;
    11     cin>>n;
    12     for(i=1;i<=n;i++)
    13         for(j=1;j<=i;j++)
    14     {
    15         cin>>D[i][j];
    16     }
    17     maxSum=D[n];////maxSum指向第n行
    18     for(int i=n-1;i>=1;i--)
    19         for(int j=1;j<=i;j++)
    20     {
    21         maxSum[j]=max(maxSum[j],maxSum[j+1])+D[i][j];
    22     }
    23     cout<<maxSum[1]<<endl;
    24     return 0;
    25 }

    第五种方法是直接利用D[n]代替int maxsum[n]
    第二种方法到第五种方法的时间复杂度都是n*n。

  • 相关阅读:
    每周一荐:代码编辑器sublime
    每周一荐:Google的序列化框架Protobuf
    每周一荐:ObjectiveC的开源开发环境GNUstep
    每周一荐:用gnuplot绘制函数曲线
    每周一荐:学习ACE一定要看的书
    临时变量管理器
    每周一荐:TotalCommand的文件夹同步功能
    每周一荐:支持latex的思维导图软件docear
    关于程序员面试的一点想法
    每周一荐:Python Web开发框架Django
  • 原文地址:https://www.cnblogs.com/cynthia-dcg/p/6697505.html
Copyright © 2011-2022 走看看