算法分析与设计--动态规划 1.数塔问题 2.最长上升子序列(LIS)

文章介绍了使用动态规划解决数塔问题和寻找数组中最长上升子序列的方法。对于数塔问题,通过自底向上的计算,更新每一层的最大路径和;而对于最长上升子序列,通过不断回溯和比较,确定以每个元素结尾的最长上升子序列长度。两种问题都具有O(n^2)的时间复杂度和O(n)的空间复杂度。
摘要由CSDN通过智能技术生成

 以下是个人见解,只可用于参考,有错误欢迎指正

一、数塔问题

如下图是一个数塔,从顶部出发在每一个节点可以选择向左或者向右走,一直走到底层,要求找出一条路径,使得路径上的数字之和最大。

 思路:

先自顶而下分析:

每层要向左走还是右走,取决于左右两边到最底层的路径长度。因此求第一层的最大路径长度要先知道第二层的最大路径长度...即要先求第四层的最大路径长度,再求上一层的最大路径长度。

因此要采用自底而上的计算。

算法实现:

首先利用一个二维数组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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值