力扣刷题记录
dp
1547. 切棍子的最小成本
思路
直接回溯模拟整个过程,毫无疑问会出现超时的情况
想使用dp数组来解决,但是没有想到如何构建该数组,于是查看题解
定义dp[i][j] 表示 i到j最小的成本
首先遍历长度 l 长度小于2 说明只有两点 那显然是不用切割的 默认值为0即可
固定长度 再遍历起点和终点 及中间的切割点 k 从而更新dp数组
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + cuts[j] - cuts[i])
代码
class Solution:
def minCost(self, n: int, cuts: List[int]) -> int:
# global res
# select = [0, n]
# visitd = [0] * len(cuts)
# res = float('inf')
# # 这个方法的时间复杂度比较高?
# def getSum(select:List[int], p):
# # 找到最接近的两个点 从 select中
# low , high = select[0], select[1]
# for i in range(len(select)):
# if p - select[i] > 0 and p - select[i] < p - low:
# low = select[i]
# if p - select[i] < 0 and p - select[i] > p - high:
# high = select[i]
# return high - low
# def backTracking(select:List[int], path:int, visitd:List[int]):
# global res
# if len(select) - 2 == len(cuts):
# if path < res:
# res = path
# return
# for i in range(0, len(cuts)):
# if visitd[i] == 0:
# cutLen = getSum(select, cuts[i])
# select.append(cuts[i])
# path += cutLen
# visitd[i] = 1
# backTracking(select, path, visitd)
# visitd[i] = 0
# path -= cutLen
# select.pop()
# backTracking(select, 0, visitd)
# return res
cuts.extend([0, n])
cuts.sort()
m = len(cuts)
dp = [ [0] * m for _ in range(m)]
for l in range(2, m):
# 枚举区间长度 l
for i in range( m - l):
# 枚举左右端点
j = i + l
dp[i][j] = inf
for k in range(i+1, j):
# 枚举切割点 k [i, k] [k, j] 加上当前的长度 cuts[j] - cuts[i]
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + cuts[j] - cuts[i])
return dp[0][-1]
时间复杂度:O(m^3)
空间复杂度:O(m^2)