动态规划解决序列问题

从41-44这四个典型问题,首先前两个就是对一个数组或者字符串进行分析,然后后面两个是对两个不同的字符串进行分析。

我们先看42

 这是只有一个数组的,然后我们需要建立一个一维数组的dp,而dp的长度就是该数组的长度,dp记录的是什么呢,dp【i】记录的应该是0-i的以i为终点坐标的子字符串的最长的大小。(子字符串的概念一定要理解清楚,例如现在一个数组为1 3 4 5 6他的子字符串有1 3 5 或者 3  4 5 6)就是随即删除一些元素etc......

 从3->2 的过程我们发现,2<3,此时我们就摒弃了前面的数据,因为题目要求连续嘛,因此,我们就不对此时的2进行操作,因此递归函数也非常的简单,每次只把当前的数据和前面的一个数据进行,比较,如果大于他,就在他的基础上+1;

if(nums[i]>nums[i-1]) dp[i] = dp[i-1]+1;else dp[i] = 1;

下面一题我认为比上面这个题要难很多,主要是思路不是特别的清楚;

子序列的问题一定要弄清楚,就是我们在整个数组或者字符串中删除一些元素后得到的数组或者字符串,就是子序列。和上面的题目不同的点其实就一个,上面的递增必须是连续的,这个不一定是连续的,而这就是和上面的不同,因为不需要连续,所以我们在比较的时候,不能只单单和前面的紧紧相邻的比较,我们要和当前的下标前面所有的数字进行比较,我们再回到我们dp数组的含义!!!我认为dp数组的含义一定一定要理解的非常清楚,才能够做对我们的题目。dp数组的含义(dp[i]为例)是以i为结尾的子字符串的最长的递增子序列的长度。我们前面提到了加入我们当前要计算当前dp[i]的长度,一定要把前面的所有子串的比较一遍,如果我们当前的数字nums[i]比前面的数字nums[j]要大,那么我们就让dp[i] = max(dp[i],dp[j]+1);

其实和上面的一个道题目差不多的,但是我们的循环遍历的次数增加了,因此整个过程变得没有那么简单,

for(int i = 1;i<nums.size();i++){

for(int j = i-1;i>=0;i--){

if(nums[i]>nums[j])//证明i可以和以nums[j]结尾的子序列组成新的递增子序列,而且长度

dp[i]  = max(dp[i],dp[j]+1);//因为要和0到i-1比较,因此要挑选出最长的那个序列。

}        

}

下面是我们的两个数组或者字符串的求子序列的相关问题:

1.最长重复子数组

我们看到两个数组求他们的连续的最长的公共子数组;还是要理解好子数组这个概念,和子序列不同的是,子数组必须是连续的一个子序列,不是相对顺序不能变,要求更苛刻,而是必须是连续的,但是呢,同时也是可以截取的,截取从0-i之间的一段连续的数字作为子数组。

这时候我们的动态规划需要建立一个二维的数组,不一定是数组哈,也可以是容器之类的。

然后我们的dp[i][j]的含义是分别以nums1[i]和nums2[j]为结尾的两个数组的最长重复子数组的长度。如果这个时候n1[i]和n2[j]相同了,那么他们的就去dp[i-1][j-1]以他们分贝的前面的子数组的最长距离,因为是子数组,必须要连续,所以只考虑前面的长度即可,然后相等的话,就dp[i][j] = dp[i-1][j-1]+1;如果不相等的话,那么肯定长度为0;

我认为基本就是这么理解吧。

再看下面一个题。

这个题有了前面题的思路,基本上还是很好写的,也是使用二维数组,但是含义还是一定要搞清楚的,其实这里的含义比前面的好理解,例如dp[i][j]就是text1[0-i]与text2[0-j]的最长的公共区域的长度。例如dp[2][1]就是“ab”和“a”的最长的距离那么我们怎么推敲呢?加入我们当前判断到t1[i]与t2[j]相同了,那么我们从他们的彼此的dp[i-1][j-1]不包含他俩的子串中的最长的距离+1就是他们的长度,但是万一不相同怎么办呢,我们从dp[i][j-1]以及dp[i-1][j]中找到最大值,就是说例如我们在"abcd"和"ace"比较的时候,发现d和e不相同,那么我们就取“abcd”和“ac”或者“abc”和“ac”的更长的长度,因为这两个都是最接近我们的"abcd"和"ace"的最长的长度的字符串了。然后现在如果我们加入e或者d并不会使他们的相同部分增加,因此就选择最大的即可。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值