算法第三章上机实践报告
7-1 数字三角形 (30 分)
给定一个由 n行数字组成的数字三角形如下图所示。试设计一个算法,计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大。
输入格式:
输入有n+1行:
第 1 行是数字三角形的行数 n,1<=n<=100。
接下来 n行是数字三角形各行中的数字。所有数字在0..99 之间。
输出格式:
输出最大路径的值。
输入样例:
在这里给出一组输入。例如:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出样例:
在这里给出相应的输出。例如:
30
问题描述:
从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大。
算法描述:
声明另一个与输入同样大小的数组,(最后一行可以不用考虑填写,)而其余空从下往上,从左往右开始,从输入数组同样位置的下一行的同一列和下一列数字中选择最大的数字,加上数组原位置上的数,填写如新数组中,填写一个新的表格。逐次往上加,第一行第一列的数即为所要的最大值。
代码:
#include <iostream>
using namespace std;
int d[101][101],w[101][101],n;
void findMax(){
for(int s=1; s<=n; s++)
d[n][s]=w[n][s];
for(int i=n-1; i>=1; i--){
for(int j=1; j<=i; j++){
if(d[i+1][j]>=d[i+1][j+1])
d[i][j]=w[i][j]+d[i+1][j];
else
d[i][j]=w[i][j]+d[i+1][j+1];
}
}
}
int main(){
cin>>n;
for(int i=1; i<=n; i++){
for(int j=1; j<=i; j++){
cin>>w[i][j];
}
}
findMax();
cout<<d[1][1];
}
时间复杂度:
进行循环时用了两个for循环语句,时间复杂度为O(n**2)。
空间复杂度:申请了一个二维数组数组 S(n)=O(n)。
心得体会:用填表的思想来解决问题,发现思路相较于递归简单清晰了很多,加上填表时候少了很多次重复的计算,复杂度大大减少,将问题简化了很多。困难就是,代码基础不扎实,在打代码的时候在循环中晕了,藏了一些小错误,例如赋值或取数时写错数组名称等,很小但也挺难找的。总的来说填表挺好玩的,如果不总是写错的话。