动态规划之子序列与子串问题分析

1、最大子序列

最大子序列是找出由数组组成的一维数组中和最大的连续子序列;O(n)

Max = 0 ;

sum = max{a[i]+sum , a[i] };

2、最大升序子序列(LIS:longestincreasing sequence)

最大升序子序列是找出由数组组成的一维数组中升序排列最长的可以不连续的子序列;

以A[i]结尾的升序子序列的长度为dis[i]



此处可以记录下来max取自哪一个Dis[j],结束之后可以倒推最大序列;

3、最长公共子串

两个字符串中最长的公共子串,要求字符连续;

A[n]     B[n]


记录dp中的最大值,最大的对角线矩阵就是最长的子串。

4、最长公共子序列(LCS:longest common sequence)

两个字符串中最长的公共子序列,要求字符可以不连续;

A[n]     B[n]


记录dp中的最大值,就是最长公共子序列

5、实现方法

有两种,一是递归,一是动态规划;

5.1 递归

  •  递归编程简单,容易理解 效率不高,有大量的重复执行
  • 递归调用,栈开销比较大
  • 只能求出长度,不能求出序列;
5.2 动态规划

Ø  采用多维数组来标示中间计算结果,避免重复计算提高效率;

Ø  采用倒推方式可以求出序列;

这是采用空间换时间。

DP输出结果的时候,一般可以输出一个结果,如果要输出多个结果的时候就比较麻烦。需要检索二维数组。

个人比较推荐动态规划,实现方便易于理解,而且产生的矩阵容易追溯相关的结果。

6、动归求最长升序子串

int LIS(int *arr , int n )  // O(n*n) 
{
		int result = 1 ;
		int m = 0 ;
		int *dp = new int[n+1] ;
		dp[1] = 1 ;
		for( int i = 2 ;i<=n ;i++)
		{
				m = 0 ;
				for( j = 1 ;j< i ; j++)
				{
						if(dp[j] > m && a[j]<a[i])
								m = dp[j] ;
				}
				dp[i] = m+1 ;
				if(dp[i] >result)
						result = dp[i] ;
		}

		delete[] dp ;
		dp = NULL ;
		return result ;
}

这里的动态数组可以使用vector实现,先写到这里,以后有空再详细写一下动归的思想和具体实现。对于解决这类问题真的是非常好用。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值