问题描述:
在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或右下走。只需要求出这个最大和即可,不必给出具体路径。
解题方法:
动态规划的题
不过课件用来演示推算,怎么从递归到递推的过程。
1.递归(从上往下)超时O(2的n次)
“用二维数组存放数字三角形。
D( r, j) : 第r行第j 个数字(r,j从1开始算)
MaxSum(r, j) : 从D(r,j)到底边的各条路径中,
最佳路径的数字之和。
问题:求MaxSum(1,1)”
但是考虑解决办法的时候,要从D[i][j]中间考虑,这是我一直考虑不到的问题。
2.记忆递归型O(n的平方)
“如果每算出一个MaxSum(r,j)就保存起来,下次用到其值的时候直接取用,则可免去重复计算。”
3.递推(大顺序是从下往上,选择最大值时又是从上往下)
对比vijos p1002
算是没有什么繁杂的细节要处理(石头要排序,最小值数组要构造,压缩路程……)
代码:
#include <iostream>
#include <algorithm>
using namespace std;
const int max_n = 101;
int D[max_n][max_n], * maxS;
int main()
{
int n;
cin >> n;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= i; j ++)
{
cin >> D[i][j];
}
maxS = D[n];
for(int i = n - 1; i >= 1; i--)
for(int j = 1; j <= i; j ++)
{
maxS[j] = max(maxS[j], maxS[j + 1]) + D[i][j];
}
cout << maxS[1] << endl;
return 0;
}