为什么我的子集总和方法不正确?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么我的子集总和方法不正确?相关的知识,希望对你有一定的参考价值。

我是动态编程的新手,并提出了我的(显然是错误的)子集和问题的方法。我想知道为什么我的方法不正确。特别是,我很好奇这个基本想法是否有效,或者我是否应该坚持对子集总和see yt的常规方法。

问题:给定一个数字数组,在数组中找到两个具有相同总和的子集。与正常子集和问题相比,此问题已稍有更改。

示例: [1,5,5,9]可以分为[1,9][5,5]

想法:

   1  5  5  9
   0  5  5  9
1  1  6  6  10
5  6  5  6  10
5  6  10 10 10
9  6  10 10 10

[而不是像往常那样跟踪我选择哪个元素,不跟踪哪个元素,我想跟踪总和。想法是在mem[i-1][j](当前位置上方一个)处找到先前元素的总和。如果该值+当前值小于或等于总和的一半(在这种情况下为20),则将当前值加到总和上。否则,我们只是采用先前的值而忽略当前值。

表中对角线上的元素将只是其自身。我这样做是因为否则我将两次添加相同的元素。

在示例中,算法将在看到第一个10时终止。

实施:

Play with the code

bool has_solution(std::vector<int> &v) 
    const long long sum = accumulate(v.begin(), v.end(), 0);
    long long mem[v.size() + 1][v.size()];
    for (int j = 0; j < v.size(); ++j) 
        mem[0][j] = v.at(j);
    
    mem[0][0] = 0;
    for(int i = 1; i < v.size(); ++i) 
        for (int j = 0; j < v.size(); ++j) 
            if (i - 1 == j) 
                mem[i][j] = v.at(i - 1);
             else 
                const long long new_sum = mem[i - 1][j] + v.at(i - 1) ;
                if (new_sum <= sum - new_sum) 
                    mem[i][j] = new_sum;
                 else 
                    mem[i][j] = mem[i - 1][j];
                
            
            if (mem[i][j] * 2 == sum) 
                return true;
            
        
    
    return false;

该算法为输入提供了错误的解决方案[987, 856, 743, 491, 227, 365, 859, 936, 432, 551, 437, 228, 275, 407, 474]。根据site,它应该返回true,但返回false。

我是动态编程的新手,并提出了我的(显然是错误的)子集和问题的方法。我想知道为什么我的方法不正确。我特别想知道...

答案

除了非标准可变长度数组的问题(请参阅Blastfurnace的注释),您的概念也不起作用。

以上是关于为什么我的子集总和方法不正确?的主要内容,如果未能解决你的问题,请参考以下文章

如何找出为啥所有数据子集的总和比总和小1

子集总和,带有回溯和类

带有 2675 个数字列表的子集总和

计算 Mat OpenCV 子集的总和

计算具有给定总和的子集的有效方法

在python中查找列表的子集的总和