【算法导论学习笔记】钢条切割(动态规划)

动态规划

先尝试着浅浅的理解一下动态规划,动态规划像是分治的某种变形,分治法是将问题分解成相同类型的子问题然后递归求解,动态规划也是差不多的说法,但是分治的子问题是相互独立的子问题,而动态规划的子问题具有相同的子子问题,避免掉这些问题的重复求解,就是动态规划。
动态规划一般用来解决最优化问题,下面的问题就是一个典型的最优化问题。

钢条切割问题(python年度更新系列)

给定一个长度为n的钢条,和钢条对应价格的价格表。

长度i:   1   2   3   4   5   6   7   8   9   10
价格Pi:  1   5   8   9   10  17  17  20  24  30 

暴力求解的话就相当于一个0-1分布,每个单位1的位置都可以选择是否切割,长度为n的钢条有n-1个位置选择,也就是 2 n − 1 2^{n-1} 2n1种不同的切割方案。

使用自顶向下的递归实现

每次切下来的那部分i不再切割,然后切割剩下的n-i,如此反复,这个情况相当于去递归的搜索这个问题
需要时间的递推公式为: T n = 1 + ∑ i = 0 n − 1 T i Tn =1 + \sum_{i=0}^{n-1}T_i Tn=1+i=0n1Ti
故时间复杂度为: 2 n 2^{n} 2n
当n超过30时,这个数值将变得恐怖如斯。

class solution(object):
	def search(p,n):
		if n == 0:
			return 0
		Max = float('-inf')
		for i in range(1,n):
			Max = max(q,p[i]+search(p,n-i))
		return Max
动态规划实现

动态规划的求解有两种思路,一是自顶向下的带备忘录的解法,另一种是自底向上的带备忘录的写法,二者的运行时间大致相同,均为 O ( n 2 ) O(n^2) O(n2)

自顶向下的动态规划:
class solution(object):
	def MEMOIZED-CUT-ROD(p,n):
		r = []
		#创建一个备忘录
		for i in range(n):
			r.append(float('-inf'))
		#创建一个数组用于记录每一次的最优情况
		return MEMOIZED-UP-CUT-ROD(p,n,r)


	def MEMOIZED-UP-CUT-ROD(p,n,r):
		if r[n] > 0:
			return r[n]
			#如果最优情况已经发生,则返回这个最优值
			#如果没有这个最优情况则去搜索
		if n == 0#钢条的长度为0时cur_best = 0
				cur_best = 0
		else:
			#否则暂时赋值为负无穷
			cur_best = float('-inf')
			#
			for i in range(1,n):
				cur_best = max(cur_best,p[i]+MEMOIZED-UP-CUT-ROD(p,n-i,r))
				#cur_best从负无穷变为1的最优情况,2的最优情况,到3的最优情况
				#也就是说max里面的cur_best代表的是不切割的收益,然后就是切割
				#的各种情况的收益,当不存在备忘录时,就是2^n的时间复杂度,但
				#存在备忘录时会避免很多子问题的重复求解,每个子问题只求解一次
		r[n] = cur_best
		return cur_best
自底向上的动态规划:

这个思路的话就不需要函数栈了,直接避免掉递归到函数底层才开始做备忘录,我直接开始解决子问题,然后不断的合并子问题

class solution(object):
	def BOTTOM-UP-CUT-ROD(p,n):
		r = []
		for i in range(n):
			r.append(float('-inf'))
		#依然是初始化一个备忘录
		r[0] = 0
		#没有钢材的时候收益是0
		for j in range(1,n):
			cur_best = float('-inf')
			for i in range(1,j):
				#不切割和切割时的最优情况,由于从1开始找,因此每次都不用递归,直接找出最优就可以
				cur_best = max(cur_best,p[i]+r[j-i])
			r[j] = cur_best
			#更新最优情况
		return r[n]

时间复杂度为: n 2 n^2 n2
成功的降为了多项式级的时间复杂度。

猜你喜欢

转载自blog.csdn.net/qq_54384621/article/details/124409410