问题:
有n根长度不等的绳子,允许剪短不允许拼接,将其分为等长的m根,求m根绳子的最大长度?
考虑用动态规划的方法:
设为将分为个的最大长度。
则有以下动态转移方程:
Python代码如下:
#coding: utf-8
def maximum_rope(arr, m):
n = len(arr)
d = [[0 for i in range(m+1)] for j in range(n)]
for i in range(1, m+1):
d[0][i] = arr[0] / i
print(d)
temp = []
for i in range(1, n):
for j in range(1, m+1):
for k in range(1, j):
temp.append(min(d[i-1][k], arr[i]/(j-k)))
# print('i:', i, 'j:', j, temp)
temp.append(d[i-1][j])
temp.append(arr[i]/j)
d[i][j] = max(temp)
temp = []
print(d[i])
print(d)
return d[-1][-1]
aa = [4, 3, 5]
print(maximum_rope(aa, 6))
算法复杂度分析,用一个n*(m+1)的矩阵表示了状态转移过程,需要填每一个元素,所以需要计算n*(m+1)个元素,对于每一个元素的填入需要从k(1->m+1)个元素里面筛选,故算法复杂度为。
算法心得:
在动态规划中对于当前的结果,当加入新的元素时可以用前面已经得到的结果,所以算法看起来复杂度很高,但如果绳子x和分的个数是一个动态增加的量,则可以用以前计算的结果,从而每次只需要的复杂度。所以对于输入是动态增加的问题,动态规划有此优势。
扩展:
基于当前计算结果计算新的结果这种思想能否用于强化学习。
debug:
Python中二维数组的声明:
d = [ [0] *n for i in range(m)]
错误类型, d = [[0] * n] * m
因为[0]*n是一个类的实例,再乘m是这个实例的m次引用,是同一个对象。