描述:
数字三角形,从三角形顶部往下走,只能往左下或右下走,求走到最下面时所经过的数字和最大为多少?(下图为n=6时的情况)
2 | ||||||||||
96 | 30 | |||||||||
83 | 52 | 60 | ||||||||
21 | 65 | 44 | 61 | |||||||
8 | 79 | 50 | 41 | 21 | ||||||
61 | 41 | 50 | 38 | 79 | 10 |
第1行:整数n(1<=n<=1000)
第2-n+1行:每行若干整数,第i行有i-1个整数,空格分隔。
输出:
经过的最大数字之和
示例测试集:
- 第1组
输入:
3
1
7 2
1 0 10
输出:
13
最差算法——遍历
#include<iostream>
using namespace std;
int tem_rsl(int now,int now_l,int now_r)
{
if (now + now_l > now + now_r)
return now + now_l;
else
return now + now_r;
}
int main()
{
int n;//输入数字的行数 1-1000
cin >> n;
int tot_n = (1 + n)*n / 2;
int* a = new int[tot_n+1];
for (int i = 1; i < tot_n + 1; i++)
{
cin >> a[i];
}
int layer = n;
int temp = n - 1;
for (int i = tot_n-n; i > 0; i--)
{
a[i] = tem_rsl(a[i], a[i + layer], a[i + layer + 1]);
temp--;
if (temp == 0)
{
layer--;
temp = layer-1;
}
}
cout << a[1] << endl;
return 0;
}
一次改进——递归解法
#include<iostream>
#define MAX 1000
using namespace std;
int n;
int a[MAX][MAX];
int findmax(int i,int j)
{
if (i == n)
{
return a[i][j];
}
else
{
int x = a[i][j] + findmax(i + 1, j + 1);
int y = a[i][j] + findmax(i + 1, j);
return x > y ? x : y;
}
}
int main()
{
//输入数字的行数 1-1000
cin >> n;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
cin >> a[i][j];
}
}
cout << findmax(1, 1) << endl;
return 0;
}
再改进——记忆递归动归程序
改进递归解法中,中间部分重复解法的情况。
#include<iostream>
#define MAX 1000
using namespace std;
int n;
int a[MAX][MAX];
int sum_max[MAX][MAX];
int findmax(int i,int j)
{
if (sum_max[i][j]!=-1)
{
return sum_max[i][j];
}
else if (i == n)
{
sum_max[i][j] = a[i][j];
return sum_max[i][j];
}
else
{
int x = a[i][j] + findmax(i + 1, j + 1);
int y = a[i][j] + findmax(i + 1, j);
if (x > y)
{
sum_max[i][j] = x;
}
else
{
sum_max[i][j] = y;
}
return sum_max[i][j];
}
}
int main()
{
//输入数字的行数 1-1000
cin >> n;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
cin >> a[i][j];
sum_max[i][j] = -1;
}
}
cout << findmax(1, 1) << endl;
return 0;
}
特别注意点:
写递归解法的步骤:1 不要考虑之后如何查找,只需要写好当前查找的办法。
2 一定要写上触底返回的情况。