动态规划-子序列问题模板-题目延伸

子问题序列模板labuladong

1.一个一维数组dp[]

1.1 最长上升子序列
动态规划的时间复杂度$O(n)$
二分查找:$O(nlogn)$,纸牌问题:纸牌只能摞在比他大的纸牌上,如果当前没有堆可以放,就另起一堆,如果有多个堆都能放,就放在最左边的堆。有几堆纸牌最长上升子序列的长度就是几。变相等价于,用二分查找找左边界。
if(a[mid]>=v) y=mid;
else x=mid+1;

最长上升子序列LIS
dp[i]表示以a[i]结尾的子序列最长子序列长度
从dp[i-1]推导dp[i],因为是以a[i]结尾的,所以a[i]一定在子序列里面,那么要找前面比a[i]小的数字结尾的最大子序列长度即可

连续子数组的最大和

dp[i]表示以a[i]结尾的最大连续和
这里必须是连续的,所以从dp[i-1]推导dp[i]的时候,dp[i]必须包含a[i],否则不连续,那么需要讨论的就是dp[i-1]的贡献

2.一个二维数组dp[][]

2.1涉及两个字符串
最长公共子序列LCS

int Lcs(char x[], char y[])
{
	int i, j, len1 = strlen(x + 1), len2 = strlen(y + 1);//strlen(x+1)是求得从第二个字符开始到结尾的长度
	memset(dp, 0, sizeof(dp));
	for (i = 1; i <= len1; ++i)
		for (j = 1; j <= len2; ++j)
		{
			if (x[i] == y[j])
				dp[i][j] = dp[i - 1][j - 1] + 1, path[i][j] = 1;
			else if (dp[i - 1][j] >= dp[i][j - 1])
				dp[i][j] = dp[i - 1][j], path[i][j] = 2;
			else
				dp[i][j] = dp[i][j - 1], path[i][j] = 3;
		}
	return dp[len1][len2];
}

只要是让两个字符串 有“相同”之类的描述,就考虑公共子序列

可以延伸出的问题:

两个字符串的最小ASCII删除和(leetcode)

注意这道题的base case 和状态转移方程,看leetcode的注释

两个字符串的删除操作(leetcode)

以上三题的思路(labuladong)

2.2涉及一个字符串
最长回文子序列
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值