【动态规划】数字三角形最大值(一)(递归)

题目:数字三角形,形如

         3

     3      2

  4     5     1

1    3     4     1

每个点只能选择向左或向右走,取一条路径,使得路径上数字和最大。

无需求出路径,求出最大值。

输入n,和 n 行数字三角形 n<=100


思路:递归解决

用二维数组 d[ l ][ r ] 存数字三角形

 if ( l  ==  n) maxSum( l , r ) = d [ l ][ r ] ;

 else maxSum ( l , r ) = max { maxSum( l+1, r ) , maxSum( l+1, r+1 ) }

很简单呀


代码如下:

#include 
#include 

using namespace std;

#define MAX 101

int d[MAX][MAX];
int n;

int MaxSum(int l,int r)
{

    if(l==n)
        return d[l][r];
    else
        return max(MaxSum(l+1,r),MaxSum(l+1,r+1))+d[l][r];

}

int main()
{

    cin >> n;

    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            cin >> d[i][j];
    cout << MaxSum(1,1) << endl;

    return 0;

}

好了,数据量大一点的时候,就华丽丽的超时了

分析一下时间复杂度,发现是 O(2^n),原因是

会 重 复 计 算 maxSum (r,l) 的值!

————————————————————————————————————————————————————————————————————————————


优化:(记忆递归型动态规划)

思路:那就把计算结果存下来嘛。


代码如下:

#include 
#include 

using namespace std;

#define MAX 101

int d[MAX][MAX];
int n;
int maxSum[MAX][MAX];

int MaxSum(int i,int j)
{
    if(maxSum[i][j]!=-1)
        return maxSum[i][j];
    if(i==n)
        maxSum[i][j] = d[i][j];
    else
        maxSum[i][j] = max(MaxSum(i+1,j),MaxSum(i+1,j+1)) + d[i][j];

    return maxSum[i][j];
}


int main()
{

    cin >> n;

    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++){
            cin >> d[i][j];
            maxSum[i][j]=-1;
        }

    cout << MaxSum(1,1) << endl;

    return 0;
}

算法时间复杂度成功变成 O(n^2);

不过递归还是慢一点,继续优化! 


你可能感兴趣的:(入门算法&数据结构)