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

为何elif语句会破坏打家劫舍问题的动态规划解法?

打家劫舍问题(Robber Problem)

小偷不能盗窃相邻房屋,需最大化劫掠金额。

示例

  • 输入: arr = [2, 10, 3, 6, 8, 1, 7]
  • 输出: 25
  • 解释: 小偷能获得的最大金额为25,通过盗窃第1、4、6号房屋(arr[1]+arr[4]+arr[6] = 10+8+7 = 25)

可正常运行的解法

def rob(arr):
    arr = tuple(arr)
    memory = {}
    
    def helper(i=0):
        if i >= len(arr):
            return 0 
            
        if i not in memory:
            steal = arr[i] + helper(i+2)
            skip = helper(i+1)
            memory[i] = max(steal, skip)
        
        return memory[i]
    
    return helper()

返回错误结果的解法(返回0)

def rob(arr):
    arr = tuple(arr)
    memory = {}
    
    def helper(i=0):
        if i >= len(arr):
            return 0 
        
        elif memory[i]:
            return memory[i]
            
        else:
            steal = arr[i] + helper(i+2)
            skip = helper(i+1)
            memory[i] = max(steal, skip)
            return memory[i]
    
    return helper()

差异原因解析

两个解法的核心差异在于缓存判断逻辑:

  1. 正确解法:用if i not in memory:判断当前索引i是否已存入缓存字典。只要i不在缓存中,就重新计算并存储结果;否则直接返回缓存值,逻辑完全正确。
  2. 错误解法:用elif memory[i]的逻辑存在致命问题:
    • 当i不在memory的键中时,直接访问memory[i]会触发KeyError异常,程序会崩溃。你提到它返回0,大概率是测试时误用了defaultdict(int)这类默认字典(访问不存在的键会返回0),但即使如此,逻辑依然错误。
    • 就算缓存中存在i,memory[i]的判断是检查值是否为真(非0、非空等)。如果某个索引的最大金额确实是0,这行代码会误以为没有缓存,进入else分支重复计算,导致逻辑混乱,最终返回错误结果。

简单来说,错误解法把「检查键是否存在」写成了「检查键对应的值是否为真」,完全偏离了缓存的正确逻辑。

内容的提问来源于stack exchange,提问作者jbuddy_13

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:20:52