数字三角形

图片发自简书App

问题描述和状态定义 —— 非负数字组成的三角形,从第一个数开始每次可以向右或者向下走一格,直到最下行,求沿途经过数和的最大值。这是一个动态决策的问题,每次都面临两种选择,如果用回溯法找所有路线,则n层三角形有2的n次方条的路线,效率很低。

所以引入状态转移的概念:

把当前位置 ( i, j)看成一个状态,定义函数 d( i, j)为从( i, j)出发后能得到的最大的和,那么可以写出一个递推方程:

d( i, j) = a( i, j) + max{ d( i, j + 1), d( i + 1, j + 1)};

d( i, j + 1)为从( i, j + 1)出发的最大和,即一个最优子结构,也可以描述成“全局最优解包含局部最优解”。上式是一个状态转移方程,状态和状态转移方程是动态规划的核心

记忆化搜索与递推
方法一:递归计算

int solve(int i , int j){
     return a[i][j] + ( i == n ? 0 : max( solve(i+1,j), solve(i+1, j+1) )   );
}  //注意处理边界

这样做正确,但重复计算


图片发自简书App

方法二: 递推计算

int i, j;
for( j = 1; j <= n; j++) d[n][j] + a[n][j];
for(int i = n-1; i >= 1; i--){
    for(int j = 1; j <= i; j++){
        d[i][j] = a[i][j] + max(d[i+1][j] , d[i+1][j+1]);
    }
}

一层一层从下至上递推,复杂度为O(N^2)

方法三:记忆化搜索

int solve(int i, int j){
    if(d[i][j] >= 0) return d[i][j];
    return d[i][j] = a[i][j] + (i == n?0:max(solve(i+1,j), solve(i+1, j+1)));
}//别忘了队d[i][j]赋值

已经搜过则判断后不再计算,直接用该值,由于i,j都在,1~n之间,所有不相同的结点一共只有O(n2)个,不论以怎样的顺序访问,时间复杂度均为O(n2)

图片发自简书App

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 问题描述 有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数,如下图。...
    sugar_coated阅读 1,163评论 0 3
  • 题目: 时间限制:10000ms单点时限:1000ms内存限制:256MB问题描述小Hi和小Ho在经历了螃蟹先生的...
    科学旅行者阅读 244评论 0 0
  • 题目 给定一个数字三角形,找到从顶部到底部的最小路径和。每一步可以移动到下面一行的相邻数字上。** 注意事项如果你...
    六尺帐篷阅读 784评论 0 3
  • 问题描述 在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左...
    icecrea阅读 741评论 0 0
  • 天地一番来去,总有世间偶遇。肤若玉石魂,落丝裙
    硕果蕾蕾阅读 335评论 3 7