动态规划:将一个问题分解为若干个子问题,对每个子问题求最优解,前一个子问题的最优解,为下面的子问题提供了有效信息,依次解决子问题,最后一个子问题就是初始问题的最优解。动态规划应用于子问题重叠的情况,子问题的划分是通过递归实现。为了避免子问题的重复计算,保证每个子问题只求解一次,会将解保存在数组中。
区间调度问题
无权区间调度问题


解决方法:贪心算法
![]()

以上排序都是错误的。


贪心算法能够更早完成任务。
带权区间调度问题


动态规划的四个步骤:
1.确定状态;
2.状态转移方案;
3.初始条件和边界情况;
4.确定计算顺序。




需要把1至n的每个值都算出来,M[0]、M[1]等

运用了递归。
背包问题

维护一个二维数组。

第二个定义中加入w容量,每放进一个物品就要减去此物品的重量。




例题
最大子数组和

此例中的OPT代表某一个连续子数组的最大和。
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
opt = [nums[0]] if nums else None
for i in nums[1:]:
opt.append(max(opt[-1]+i,i))
return max(opt)
最长公共子序列



练习:
最长回文子序列
最长公共子序列的改版,即找反转后的序列与原序列之间的最大公共子序列。
给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。
子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
class Solution:
def longestPalindromeSubseq(self, s: str) -> int:
rs = s[::-1]
len1,len2 = len(s),len(rs)
D = [[0 for j in range(len2+1)] for i in range(len1+1)]
#设置初始值
for i in range(len1):
D[i][0] = 0
for j in range(len2):
D[0][j] = 0
#字符串从0开始存储数据,根据状态转移方程
for i in range(len1):
for j in range(len2):
if s[i] == rs[j]:
D[i+1][j+1] = D[i][j] + 1
else:
D[i+1][j+1] = max(D[i+1][j],D[i][j+1])
return D[len1][len2]
257

被折叠的 条评论
为什么被折叠?



