数字三角形
题目详情
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
在上面的三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字和最大.路径上的每一步都只能往左下或者右下走.只需要求出这个最大和即可,不必给出具体路径.
三角形的行数大于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 MaxSum(int i, int j)
{
if(maxSum[i][j]!=-1)
return maxSum[i][j];
if(i==n)
maxSum[i][j]=D[i][j];
else
{
int x=MaxSum(i+1,j);
int y=MaxSum(i+1,j+1);
maxSum[i][j]=max(x,y)+D[i][j];
}
return maxSum[i][j];
}
int main()
{
int i,j;
cin>>n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
{
cin>>D[i][j];
maxSum[i][j]=-1;
}
cout<<MaxSum(1,1)<<endl;
}
由于遍历每条路径,存在大量重复计算,所以不建议采用.下面让我们来简化计算,利用递推,将计算好的值利用MaxSum(i,j)保存起来,避免重复计算.
递推程序
#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用一维数组代替.然后由下往上计算,先由一维数组记录最后一行数据,然后加上上一行二维数组存储的数,将最大值记录在一维数组中和二维数组列数相同的位置,以此类推如图:
原始底层:
4 5 2 6 5
向上一行计算:
7 12 10 10 5
再向上一层:
20 13 10 10 5
优化后的递推
#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(j=1;j<=i;j++)
{
cin>>D[i][j];
}
maxSum=D[n];//maxSum指向第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;
}
计算机201 qyj
787

被折叠的 条评论
为什么被折叠?



