算法思想:秒解动态规划

1.1斐波那契数列问题

方法1:递归解法
def fibnacci(n):
	if n==1 or n==2:
		return 1
	else:
		return fibnacci(n-1)+fibnacci(n-2)
问题:子问题重复计算
# f(5)=f(4)+f(3)
# f(4)=f(3)+f(2)
# f(3)=f(2)+f(1)
# f(3)=f(2)+f(1)
# f(2)=f(1)
方法2:非递归解法,可以理解为动态规划的思想
最优子结构:递推式+重复子问题
子问题存起来
def fibnacci_no_recursion(n):
	f=[0,1,1]
	if n >2:
		for i in range(n-2):
			num=f[-1]+f[-2]
			f.append(num)
	return f[n]
print(fibnacci(100))

1.2钢条切割问题

在这里插入图片描述

问题:现有一段长度为的钢条和上面的价格表,求切割钢条
方案,使得总收益最大。

在这里插入图片描述
最优子结构

  • 可以将求解规模为的原问题,划分为规模更小的子问题:完成一次切割
    后,可以将产生的两段钢条看成两个独立的钢条切个问题。

  • 组合两个子问题的最优解,并在所有可能的两段切割方案中选取组合收
    益最大的,构成原问题的最优解。

  • 钢条切割满足最优子结构:问题的最优解由相关子问题的最优解组合而
    成,这些子问题可以独立求解。
    在这里插入图片描述

  • 递归:自顶向下实现

# p=[0,1,5,8,9,10,17,17,20,21,23,24,26,27,27,28,30,33,36,39,40]
p=[0,1,5,8,9,10,17,17,20,24,30]
#方法1:
def cut_rod_recurision_1(p,n):
	if.n==0:
		return 0
	else:
		res= p[n]
		for i in range(1,n):
			res max(res,cut_rod_recurision(p,i)+cut_rod_recurision(p,n-i)) #重复计算
		return res
# 递归2
def cut_rod_recurision_2(p,n):
	if.n==0:
		return 0
	else:
		res=0
		for i in range(1,n+1):
			res max(res,p[i]+cut_rod_recurision_2(p,n-i)) 
		return res

  • 动态规划:自底向上实现
  • 递归算法由于重复求解相同子问题,效率极低
  • 动态规划的思想:
    • 每个子问题只求解一次,保存求解结果
    • 之后需要此问题时,只需查找保存的结果
def cut_rod_dp(p,n):
	r=[0]
	for i in range(1,n+1):
		res 0
		for j in range(1,i+1):
			res max(res,p[j]+r[i j])
		r.append(res)
	return r[n]
  • 重构解
    在这里插入图片描述
def cut_rod_extend(p,n):
	r.=[0]
	s=[0]
	for i in range(1,n+1):
		res_r=O#价格的最大值
		res_s.=O#价格最大值对应方案的左边不切割部分的长度
		for j in range(1,i 1):
			if p[j]+r[i j]>res_r:
				res-r=p[j]+.r[i.-j门
				res_s=j
		r.append(res_r)
		s.append(res_s)
	return r[n],s
def cut_rod_solution(p,n)
	r,s=cut_rod_extend(p,n)
	ans=[]
	while n>0:
		ans.append(s[n])
		n-=s[n]

总结

  • 动态规划问题关键特征
  • 什么问题可以使用动态规划方法?
  • 最优子结构
    • 原问题的最优解中涉及多少个子问题
    • 在确定最优解使用哪些子问题时,需要考虑多少种选择
  • 重叠子问题

1.3最长公共子序列

一个序列的子序列是在该序列中删去若干元素后得到的序列。
例:“ABCD”和“BDF”都是“ABCDEFG”的子序列
最长公共子序列(LCS)问题:给定两个序列X和Y,求X和Y长度最大的公共子
序列。
D例:X="ABBCBDE"Y="DBBCDB"LCS(X,Y)=“BBCD”
应用场景:字符串相似度比对
思考:暴力穷举法的时间复杂度是多少?
2的m+n次方
思考:最长公共子序列是否具有最优子结构性质?有
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值