数字三角形就是用户输入行数n,输入一个三角形,要求计算出第一行到最后一行的最大路径和。
看这个题初学小白一开始真的有点难想,后来看了很久的动态规划课程才明白过来,一定要学会画图来思考!
比如要算下面一个三角形的最大路径和,n=5
7 | ||||
3 | 8 | |||
8 | 1 | 0 | ||
2 | 7 | 4 | 4 | |
4 | 5 | 2 | 6 | 5 |
直接从第一行算,然后分析只能走下面一行的正下方或者是右下边,采用递归的话就会很麻烦并且会超时,数值过大的话。
所以要从最后一行开始计算哦,最后一行到底部的路径就是他们自己的数值,所以这个就是初始化条件,也就是边界值哦,然后再看倒数第二行,依次往上计算(就是倒数第二行就是第二行自己的数加上最后一行的两个数中的较大值相加)。要定义一个二维数组来存放最大总和路径maxSum[MAX][MAX],用另外一个二维数组存放数字三角形的值D[MAX][MAX]。
1.先读入三角形的数值到D[i][j]
2.进行最后一行的初始化,即maxSum[n][i]=D[n][i].
3.根据动态方程maxSum[i][j]=max(maxSum[i+1][j],maxSum[i+1][j+1])+D[i][j]递归计算
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX=101;
int D[MAX][MAX];
int maxSum[MAX][MAX];
/*
样例运行
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
结果是30
*/
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
for(int 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;
return 0;
}
小小优化版本
为什么会有优化的版本因为用表格看的话,其实只需要最后一行的数值就可以哦,把maxSum定义为一维数组即可,滚动数组求解更优化空间结构,但是时间复杂度不变的哦
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX=101;
int D[MAX][MAX];
int maxSum[MAX];
/*
样例运行
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
结果是30
*/
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
cin>>D[i][j];//输入每一行数字三角形的每一个数值
}
}
for(int i=1;i<=n;i++)//最后一行初始化
{
maxSum[i]=D[n][i];
}
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;
return 0;
}