1、最大子序列
最大子序列是找出由数组组成的一维数组中和最大的连续子序列;O(n)
Max = 0 ;
sum = max{a[i]+sum , a[i] };
2、最大升序子序列(LIS:longestincreasing sequence)
最大升序子序列是找出由数组组成的一维数组中升序排列最长的可以不连续的子序列;
以A[i]结尾的升序子序列的长度为dis[i]
此处可以记录下来max取自哪一个Dis[j],结束之后可以倒推最大序列;
3、最长公共子串
两个字符串中最长的公共子串,要求字符连续;
记录dp中的最大值,最大的对角线矩阵就是最长的子串。
4、最长公共子序列(LCS:longest common sequence)
两个字符串中最长的公共子序列,要求字符可以不连续;
记录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实现,先写到这里,以后有空再详细写一下动归的思想和具体实现。对于解决这类问题真的是非常好用。