分析过程:
- 识别子问题 sub-problems dividing
- 识别子问题中的重叠特点 over-lapping sub-problem
- 存储子问题的答案 cache sub-solutions
- 合并问题答案 combine solutions
- 解析答案 parse solutions
问题:木头价格如下
[1, 5, 8, 9, 10, 17, 17, 20, 24, 30, 33] 下表加一为米数,值为价格
给出一段木头的长度,怎么切分价格最高?
"""
Cutting Problem
All the dynamic programming:
1. sub-problems
2. Overlapping sub-problems
3. parse solution
"""
from collections import defaultdict
from functools import lru_cache
# least recent used
prices = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30, 33]
complete_price = defaultdict(int)
for i, p in enumerate(prices): complete_price[i+1] = p
solution = {}
cache = {}
#<- if when n .... is huge. size(cache)
# keep most important information.
@lru_cache(maxsize=2**10)
def r(n):
# a very classical dynamic programming problem
# if n in cache: return cache[n]
candidates = [(complete_price[n], (n, 0))] + \
[(r(i) + r(n-i), (i, n - i)) for i in range(1, n)]
optimal_price, split = max(candidates)
solution[n] = split
# cache[n] = optimal_price
return optimal_price
def parse_solution(n, cut_solution):
left, right = cut_solution[n]
if left == 0 or right == 0: return [left+right, ]
else:
return parse_solution(left, cut_solution) + parse_solution(right, cut_solution)
if __name__ == '__main__':
print(r(19))
print(solution)
print(parse_solution(19, solution))