� 先分别求解路线 1 和路线 2 上的最大值。路线 1 的最大值为 3,路线 2
上的最大值是 8。
� 然后求解出路线 1 和路线 2 两者之间的最大值 8。 把求得的结果和出
发点的数字 7 相加,7+8=15 就是最后答案。
只有 2 行时,兔子能获得的最多萝卜数为 15,肉眼便能看的出来。
前面是假设第 3 行之后都不存在,现在把第 3 行放开,则路线 1 路线
2 的最大值就要发生变化,但是,对于原始问题来讲,可以不用关心路线 1
和路线 2 是怎么获取到最大值,交给子问题自己处理就可以了。
反正,到时从路线 1 和路线 2 的结果中再选择一个最大值就是。
把第 3 行放开后,路线 1 就要重新更新最大值,如上图所示,路线 1 也可
以分解成子问题,分解后,也只需要关心子问题的返回结果。
� 路线 1 的子问题有 2 个,路线 1_1 和路线 1_2。求解 2 个子问题的最大值后,
再在 2 个子问题中选择最大值 8,最后路线 1 的最大值为 3+8=11。
� 路线 2 的子问题有 2 个,路线 2_1 和路线 2_2。求解 2 个子问题的最大值后,
再在 2 个子问题中选择最大值 2,最后路线 2 的最大值为 8+2=10。
当第 3 行放开后,更新路线 1 和路线 2 的最大值,对于原始问题而言,它只
需要再在 2 个子问题中选择最大值 11,最终问题的解为 7+11=18。
如果放开第 4 行,将重演上述的过程。和原始问题一样,都是从一个点出
发,求解此点到目标行的最大值。所以说,此问题是存在子问题的。
并且,只要找到子问题的最优解,就能得到最终原始问题的最优解。不仅存在
子问题,而且存在最优子结构。
显然,这很符合递归套路:递进给子问题,回溯子问题的结果。
� 使用二维数列表保存三角形数列中的所有数据。
a=[[7],[3,8],[8,1,2],[2,7,4,4],[4,5,2,6,5]]。
� 原始问题为 f(0,0)从数列的(0,0)出发,向左下角和右下角前行,一
直找到此路径上的数字相加为最大。
f(0,0)表示以第 1 行的第 1 列数字为起始点。
� 分解原始问题 f(0,0)=a(0,0)+max(f(1,0)+f(1,1))。
� 因为每一个子问题又可以分解,让表达式更通用
f(i,j)=a(i,j)+max(f(i+1,j)+f(i+1,j+1))。
(i+1,j)表示 (i,j)的左下角,(i+1,j+1)表示 (i,j)的右下角,
编码实现:
#include <iostream>
using namespace std;
//
使用二维数组存储问题域中的数据