动态规划算法 (Dynamic Programming,DP)

动态规划算法 (Dynamic Programming,DP)

算法思想

种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路

经典使用场景

1:最长有效括号

题目

给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”

代码
/*
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。
dp 动态规划问题
1:首先明确,有)才会有完整的有效括号,如果(我们要往后遍历,由于我们使用的是动态规划,把问题分解成小问题,那就得向遍历前面的小问题。
2:)可能为第一个,所以我们从第二个开始遍历。
3:)前一个可能为(,那我们可以直接获取前面的最优解。然后进行+2;
4:)前面可能是),但是这个)前面已经匹配,那就寻找前面的)哪个匹配的( 前一个是否为) 如果不为嘛,那就这个无效,
*/
int longestValidParent1heses(string s) 
{
	int len = s.size();
	int resmax = 0;//保存最大值
	if (len <= 1) return 0;
	vector<int> dp(len,0);//初始化记录容器
	for (int i = 1; i < len;i++)
	{
		if (s[i] == ')')//1:首先明确,有)才会有完整的有效括号,如果(我们要往后遍历,由于我们使用的是动态规划,把问题分解成小问题,那就得向遍历前面的小问题。
		{
			if (s[i - 1] == '(')//3:)前一个可能为(,那我们可以直接获取前面的最优解。然后进行+2;
			{
				dp[i] = ((i >= 2) ? dp[i - 2] : 0) + 2;
			}
			else if (i-dp[i-1]>0&&s[i-dp[i-1]-1]=='(')//4:)前面可能是),但是这个)前面已经匹配,那就寻找前面的)哪个匹配的( 前一个是否为) 如果不为嘛,那就这个无效,
			{
				dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
			}
			resmax = max(resmax, dp[i]);
		}
	};
	return resmax;
}
解法及解析

这里的状态转移方程比较简单,但是背包问题都是这种套路比较好理解。主要记住,动态规划就是分解问题,从小问题开始求,但解不是最后的解
中间可能会发生状态的改变,这也就是动态规划的优,你要深思这个状态转移过程,多思考,一定有收获。

2:串联所有单词的字串

题目
代码
解法及解析

3:最长无重复字符串

题目
代码
解法及解析

参考资料

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值