dp专题
Posted wory
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dp专题相关的知识,希望对你有一定的参考价值。
1. Leetcode 943
解法一:
1 class Solution: 2 def shortestSuperstring(self, A): 3 self.min_path = [] 4 self.min_length = float("inf") 5 self.get_dis_mat(A) 6 for i in range(len(A)): 7 self.dfs(len(A), i, [i], 0) 8 9 res = A[self.min_path[0]] 10 for i in range(1, len(A)): 11 cut = 30 - self.dis_mat[self.min_path[i - 1]][self.min_path[i]] 12 res += A[self.min_path[i]][cut:] 13 return res 14 15 def get_dis_mat(self, A): 16 n = len(A) 17 self.dis_mat = [[0] * n for _ in range(n)] 18 for i in range(n): 19 for j in range(n): 20 self.dis_mat[i][j] = self.cal_dis(A[i], A[j]) 21 print(self.dis_mat) 22 23 def dfs(self, total, cur, path, min_len): 24 if min_len >= self.min_length: 25 return 26 if len(path) == total and min_len < self.min_length: 27 self.min_path = copy.copy(path) 28 self.min_length = min_len 29 for nex in range(total): 30 if nex not in path: 31 path.append(nex) 32 self.dfs(total, nex, path, min_len + self.dis_mat[cur][nex]) 33 path.pop() 34 35 def cal_dis(self, str1, str2): 36 # 用30 - i将最大路径问题转换成最小路径,方便截枝 37 for i in range(min(len(str1), len(str2)), -1, -1): 38 if str2[:i] == str1[-i:]: 39 return 30 - i 40 return 30
解法二:
1 class Solution: 2 def shortestSuperstring(self, A): 3 dis_mat = self.get_dis_mat(A) 4 n = len(A) 5 dis_dp, path_dp = self.dp(A, n, dis_mat) 6 cur = min(range(n), key=lambda x: dis_dp[-1][x]) 7 s, path = (1 << n) - 1, [cur] 8 while path_dp[s][cur] != -1: 9 prev = path_dp[s][cur] 10 path.append(prev) 11 s -= (1 << cur) 12 cur = prev 13 path.reverse() 14 res = A[path[0]] 15 for i in range(1, n): 16 cut = dis_mat[path[i - 1]][path[i]] 17 res += A[path[i]][cut:] 18 return res 19 20 def cal_dis(self, str1, str2): 21 for i in range(min(len(str1), len(str2)), -1, -1): 22 if str2[:i] == str1[-i:]: 23 return i 24 return 0 25 26 def get_dis_mat(self, A): 27 n = len(A) 28 dis_mat = [[float("inf")] * n for _ in range(n)] 29 for i in range(n): 30 for j in range(n): 31 dis_mat[i][j] = self.cal_dis(A[i], A[j]) 32 return dis_mat 33 34 def dp(self, A, n, dis_mat): 35 dis_dp = [[float("inf")] * n for _ in range(1 << n)] 36 path_dp = [[-1] * n for _ in range(1 << n)] 37 for i in range(n): 38 dis_dp[1 << i][i] = len(A[i]) 39 for s in range(1 << n): 40 for i in range(n): 41 if s & (1 << i) == 0: 42 continue 43 for j in range(n): 44 if dis_dp[s - (1 << i)][j] + len(A[i]) - dis_mat[j][i] < dis_dp[s][i]: 45 dis_dp[s][i] = dis_dp[s - (1 << i)][j] + len(A[i]) - dis_mat[j][i] 46 path_dp[s][i] = j 47 return dis_dp, path_dp
以上是关于dp专题的主要内容,如果未能解决你的问题,请参考以下文章