题目:数字三角形,从顶部出发,在每一结点可以选择向左走或得向右走,一直走到底层,要求找出一条路径,该路径上的数字和最大,输出这个最大值。
(1)样例输入:
第一行是数塔层数N(1<=N<=100)。
第二行起,从一个数字按数塔图形依次递增,共有N层。
5
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11
思路:递归解决
用二维数组 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 <iostream>
- #include <algorithm>
- 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 <iostream>
- #include <algorithm>
- 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);
不过递归还是慢一点,继续优化!