递归转成递推
在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或右下走。只需要求出这个最大和即可,不必给出具体路径。 三角形的行数大于1小于等于100,数字为0- 99
从最后一排向上进行计算,比较左下和右下较大的数值加上自身,计算到第一行的时候即得最大路径值。
#include <iostream>
#include <algorithm>
using namespace std;
#define MAX 101
int D[MAX][MAX];
int n;
int maxSum[MAX][MAX];
int main()
{
int i,j;
cin >> n;
for(i = 1;i <= n;i++)
{
for(j = 1;j <= i;j++)
{
cin >> D[i][j];
}
}
for(int i = 1;i <= n;i++)
{
maxSum[n][i] = D[n][i];
}
for(int i = n - 1;i >= 1;i--)
{
for(int j = 1;j <= i;j++)
{
maxSum[i][j] = max(maxSum[i + 1][j],maxSum[i + 1][j + 1]) + D[i][j];
}
}
cout << maxSum[1][1] << endl;
}
空间优化
没必要用二维maxSum数组存储每一个MaxSum(r,j),只要从底层一行行向上递推,那么只要一维数组maxSum[100]即可,即只要存储一行的MaxSum值就可以。 进一步考虑,连maxSum数组都可以不要,直接用D的第n行替代maxSum即可。节省空间,时间复杂度不变。
#include <iostream>
#include<algorithm>
using namespace std;
#define MAX 101
int D[MAX][MAX];
int n;
int * maxSum;
int main()
{
int i,j;
cin >> n;
for(i = 1;i <= n;i++)
{
for(int j = 1;j <= i;j++)
{
cin >> D[i][j];
}
}
maxSum = D[n];
for(int i = n - 1;i >= 1;i--)
{
for(int j = 1;j <= i;j++)
{
maxSum[j] = max(maxSum[j],maxSum[j + 1]) + D[i][j];
}
}
cout << maxSum[1] << endl;
}