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

0-1背包记忆化递归TLE原因排查及变量名影响分析

0-1背包记忆化递归TLE问题解答

首先明确结论:变量名长度绝对不可能导致TLE。C++代码在编译阶段就会把自定义的变量名替换为对应内存地址、寄存器的引用,程序运行阶段根本不存在解析变量名的开销,不管你变量名是1个字母还是100个字母,编译后生成的机器码没有任何区别,你遇到的TLE完全是代码本身的写法问题导致的。


你代码超时的核心原因

  • 递归函数vector参数使用值传递,产生巨量无意义拷贝开销
    你写的knapsack函数前两个参数是vector<int> A , vector<int> B,是值传递形式;而AC代码对应的参数是vector<int>& wt, vector<int>& val,是引用传递。值传递意味着每一次递归调用,都会完整复制一遍整个物品价值数组、重量数组,当测试用例物品数量多、递归调用次数达到十万、百万级时,反复拷贝数组的时间和内存开销会被放大到极其夸张的程度,这是导致超时的最主要原因。
  • 存在大量重复递归计算,平白翻倍运行开销
    你的代码在计算出dp值存入数组后,返回时没有直接使用已经算好的结果,反而把整个递归计算逻辑又执行了一遍:
    // 问题代码片段
    if(B[n-1]<=weight){
        // 第一次执行两个递归分支,算出结果存入dp
        dp[weight][n] = max( (knapsack(A,B,weight,n-1,dp)) , (A[n-1] + knapsack(A,B,weight-B[n-1],n-1,dp))  );
        // 完全重复执行第二次一模一样的递归计算,之前算的dp值根本没用上
        return max( (knapsack(A,B,weight,n-1,dp)) , (A[n-1] + knapsack(A,B,weight-B[n-1],n-1,dp))  );
    }
    else{
        // 同样的问题:存dp时算一次,返回时又算一次
        dp[weight][n] = knapsack(A,B,weight,n-1,dp);
        return knapsack(A,B,weight,n-1,dp);
    }
    
    这等于每个状态的计算量直接翻了一倍,递归层数越深,重复计算带来的开销增长越明显。而AC代码采用return dp[n][W] = 计算逻辑的写法,每个状态只计算一次,计算完直接存入dp同时返回,没有任何冗余调用。
  • 补充:你和AC代码的dp数组维度顺序(是[容量][物品数]还是[物品数][容量])对运行速度影响极小,不会导致超时。

消除TLE的可行修复方案

  • 第一步:把knapsack函数的前两个vector参数改成引用传递,加上&符号,彻底消灭递归过程中反复拷贝数组的开销。
  • 第二步:删除所有重复的递归计算逻辑,所有分支直接返回dp[w][n] = 计算表达式的结果,保证每个状态只计算一次,不要先给dp赋值再重新跑一遍递归返回结果。
  • 可选优化:如果修改后仍卡时间,可以把记忆化递归改成自底向上的迭代式动态规划,省去递归函数调用的栈开销,运行速度会进一步提升,但只要改完前两个问题,记忆化递归的时间复杂度已经是标准的O(N*C),完全可以通过所有测试用例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 08:03:19