前文
本博客是博主在备战算法比赛时参考MOOC算法课程学习的记录,MOOC算法课链接:https://www.icourse163.org/u/mooc1456736596782?userId=1015101381&trace_c_p_k2=af370b574aff48c2aa5bc9817c45a0d5
如有侵权,请联系本人,本人立即删除!!!!
最后郭炜老师是一个很有个性的老师,我很喜欢他,算法课程讲的也很好,此博文仅供学习。
问题描述(POJ1163)
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
(图1)(等腰三角形)
图1显示了一个数字三角形。编写一个程序,计算从顶部开始到底部某个地方的路由上传递的最大数字和。每个步骤可以向左斜向下或向右斜向下。
输入值
您的程序将从标准输入中读取。第一行包含一个整数N:三角形中的行数。接下来的N行描述了三角形的数据。三角形中的行数> 1但<=100。三角形中的行数(所有整数)在0到99之间。
输出量
您的程序将写入标准输出。最高和写为整数。
样本输入
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
样本输出
30
代码实现1(时间复杂度过高,具有重复计算。0(2^n)
#include<iostream>
#include<algorithm>
using namespace std;
int array[101][101];
int fun(int i,int j,int n)
{
if(i==n)
{
return array[i][j];
}
else
{
return max( fun( i + 1 , j , n ),fun( i + 1 , j + 1 , n)) + array[i][j];
}
}
int main()
{
int n = 0;
cin >> n;
for (int i = 0; i < n;++i)
{
for (int j = 0; j <= i;++j)
{
cin >> array[i][j];
}
}
cout << fun(0, 0, n - 1) << endl;
return 0;
}
代码实现2(具有减少重复计算(用maxsum[i][j]来记录)时间复杂度O(n^2)
#include<iostream>
#include<algorithm>
using namespace std;
int array[101][101];
int maxsum[101][101];
int Maxsum(int i,int j , int n)
{
if(maxsum[i][j]!=-1) //如有记录则返回 ,减少重复计算
{
return maxsum[i][j];
}
if(i == n-1)
{
maxsum[i][j] = array[i][j];
}
else
{
int x = Maxsum(i + 1, j, n);
int y = Maxsum(i + 1, j + 1, n);
return max(x, y) + array[i][j];
}
return maxsum[i][j];
}
int main()
{
int n = 0;
cin >> n;
for (int i = 0; i < n;++i)
{
for (int j = 0; j <= i;++j)
{
cin >> array[i][j];
maxsum[i][j] = -1;
}
}
cout << Maxsum(0, 0, n)<<endl;
return 0;
}
代码实现3(递推式,从最后一行开始递推,最后i-1行记录第i行中相对位置的最大值,到最后第1行的值即为数组三角形最大的和)
#include<iostream>
using namespace std;
int main()
{
int array[101][101] = {0};
int n = 0;
int *maxsum;
cin >> n;
for (int i = 0; i < n;++i)
{
for (int j = 0; j <= i;++j)
{
cin >> array[i][j];
}
}
maxsum = array[n - 1]; //指针指向最后一行
for (int i = n - 2; i >= 0;--i)
{
for (int j = 0; j <=i;++j)
{
maxsum[j] = max(maxsum[j], maxsum[j + 1]) + array[i][j]; //maxsum = 当前位置的array[i][j]加上第i+1行的j和j+1中记录的最大maxsum值
}
}
cout << maxsum[0];
return 0;
}