为何仅用序列长度与结束位置即可记忆化最长可整除子集?
关于最长可整除子集记忆化状态的疑问
我们的目标是找到最长可整除子集(子集中任意两个元素i、j满足i可被j整除或j可被i整除)。常规解法是先对数组排序,利用整除传递性:若a可被b整除,b可被c整除,则a也可被c整除。
以下是未记忆化的递归实现:
def largestDivisibleSubset0(self, nums: List[int]) -> List[int]: def backtrack(candidate, end): if len(candidate) > len(self.best): self.best = candidate[:] if end == n - 1: return for new_end in range(end+1, n): if not candidate or candidate[-1] % nums[new_end] == 0: backtrack(candidate+[nums[new_end]], new_end) nums.sort(reverse=True) n = len(nums) self.best = [] backtrack([], -1) return self.best
随后尝试加入记忆化实现(注:代码中同时维护self.best和memo的写法不够规范,未缓存局部最优而是全局最优):
def largestDivisibleSubset(self, nums: List[int]) -> List[int]: def backtrack(candidate, end): if (len(candidate), end) in memo: return memo[(len(candidate), end)] if len(candidate) > len(self.best): self.best = candidate[:] if end == n - 1: return for new_end in range(end+1, n): if not candidate or candidate[-1] % nums[new_end] == 0: backtrack(candidate+[nums[new_end]], new_end) memo[(len(candidate), end)] = self.best nums.sort(reverse=True) n = len(nums) self.best = [] memo = {} backtrack([], -1) return self.best
我的疑问是:为何仅用当前候选序列的长度和结束位置就能准确表示状态?若两个长度相同的序列分别以5和4结尾,是否可能后者被提前剪枝,错失后续更长的可整除子集?
内容的提问来源于stack exchange,提问作者Alec
相关产品推荐
相关产品推荐

