You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何仅用序列长度与结束位置即可记忆化最长可整除子集?

关于最长可整除子集记忆化状态的疑问

我们的目标是找到最长可整除子集(子集中任意两个元素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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 14:31:11