以下是个人见解,只可用于参考,有错误欢迎指正
一、数塔问题
如下图是一个数塔,从顶部出发在每一个节点可以选择向左或者向右走,一直走到底层,要求找出一条路径,使得路径上的数字之和最大。
思路:
先自顶而下分析:
每层要向左走还是右走,取决于左右两边到最底层的路径长度。因此求第一层的最大路径长度要先知道第二层的最大路径长度...即要先求第四层的最大路径长度,再求上一层的最大路径长度。
因此要采用自底而上的计算。
算法实现:
首先利用一个二维数组data存储数塔的原始数据,然后利用一个中间数组dp存储每一次决策过程中的结果。
1.初始化dp,将data的最后一层拷贝到dp中。dp[n][j] = data[n][j] (j = 1, 2, …, n) 其中,n为数塔的层数。
2.对每一层有:dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + data[i][j]。
3.最后的结果存在dp[0][0]中。
目标函数:dp[i][j]表示相邻两行之间每步的最大值
边界:dp[n-1][j]=data[n-1][j]
状态转移方程:dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + data[i][j](0<=i<n-1)
答案:dp[0][0]
具体可参考博客:http://t.csdn.cn/323Y4
二、最长上升子序列(LIS)
在a1,a2,…,an中,一个k长度子序列指ai1,ai2,…,aik,使得1≤i1<i2<…<ik≤n. 如果ai<ai2<…<ai,请输出k的最大值.(即求出数组a的最长上升子序列长度) 。
解释:
子序列
所谓的子序列就是在原来序列中找出一部分组成的序列。
与子段不同,不需要连续的某一段,但是要保持原序列的先后顺序
最长上升子序列
在子序列的基础上,后一项大于前一项。
思路:
我们要求n个数的最长上升子序列,可以求前n-1个数的最长上升子序列,再跟第n个数进行判断。求前n-1个数的最长上升子序列,可以通过求前n-2个数的最长上升子序列……最后只剩一个数,再向后回溯。
目标函数:F [ i ] 代表以 A [ i ] 结尾的 LIS 的长度
状态转移方程:F [ i ] = max { F [ j ] + 1 ,F [ i ] } (1 <= j < i,A[ j ] < A[ i ])
边界:F [ i ] = 1 (1 <= i <= n)
答案:F(i)=max{F(1),F(2),……,F(i)}
时间复杂度:O (n^2)
空间复杂度:O(n)
具体可参考博客:http://t.csdn.cn/gfbEJ