【问题标题】:What is wrong with this code for the classic 'Subset Sum' problem? [closed]对于经典的“子集和”问题,这段代码有什么问题? [关闭]
【发布时间】:2021-10-31 21:21:42
【问题描述】:

问题陈述:给定一个整数列表 (nums) 和一个整数 x,检查列表中的某些(可能是所有)元素是否在添加时给出 x。

解决方案:

int dp[20001];
int recurse(vector<int>& nums, int x, int i) {
        
    if (x == 0)
        return 1;
        
    if (i < 0 or x < 0)
        return 0;
        
    if (dp[x] != -1)
        return dp[x];
        
    return dp[x] = recurse(nums, x - nums[i], i - 1) or recurse(nums, x, i - 1);
}
bool canPartition(vector<int>& nums, int x) {
        
    memset(dp, -1, sizeof dp);
    return recurse(nums, x, nums.size() - 1);
}

问题出在最后一行。如果我更改递归的顺序,即首先 recurse(nums, x, i - 1) 然后 recurse(nums, x - nums[i], i - 1),我会得到错误的结果。 例如,[1, 2, 3, 4, 5, 6, 7] -> 错误

我猜这与将明显错误的值放入 dp 数组有关,然后再次查找时返回相同的值。但请进一步澄清。看不透。

PS:dp数组的所有元素最初都是-1。

【问题讨论】:

    标签: c++ algorithm dynamic-programming


    【解决方案1】:

    您的dp 数组仅取决于x 的值。但它应该取决于xi

    举个例子:

    假设 nums = [1, 2, 3, 13] 和 x=13。

    那么 recurse(nums, 13, 3) 应该返回 1,但 recurse(nums, 13, 2) 应该返回 0。使用您的代码,如果您首先调用 recurse(nums, 13, 2),那么 dp[13] 将被分配一个不正确的结果。如果您有两个单独的条目dp[13][3]dp[13][2],那么就不会有问题。

    【讨论】:

    • prnt.sc/1r1a8ui 如您所见,它给出了想要的结果
    • @SaptarshiGanguly 是的,但如果你先调用 recurse(nums, 13, 2) 后跟 recurse(nums, 13, 3),那么你会得到不正确的结果。
    猜你喜欢
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    相关资源
    最近更新 更多