使用动态编程确定是否存在给定n个数字的3分区

时间:2013-03-26 01:18:32

标签: dynamic-programming partition-problem

我找到了3分区问题的解决方案,也就是说,给定n个数,你确定是否可以形成三个(分离)子集,使得所有子集都相等(即,每个子集的总和等于总和n个数字/ 3)。

类似的问题是:3-PARTITION problem。但是,我正在寻找以下代码的解释。

简单地说,我不知道发生了什么。我不知道T是什么,我或者是什么,k是什么,或者为什么我们k和j从N开始并且正在递减,什么" T [j + C [i]] [ k] =真; T [j] [k + C [i]] =真"意味着,或者为什么我们返回T [N / 3]?

bool T[10240][10000];
bool partition( vector< int > C ) {
    // compute the total sum
    int n = C.size();
    int N = 0;

    for( int i = 0; i < n; i++ ) N += C[i];
    // initialize the table
    T[0][0] = true;
        memset(T, 0, 10000^2);

    // process the numbers one by one
    for( int i = 0; i < n; i++ ) {
                for (int j = N; j >= 0; --j) {
                        for (int k = N; k >= 0; --k) {
                                if (T[j][k]) {
                                        T[j + C[i]][k] = true;
                                        T[j][k + C[i]] = true;
                                }
                        }
                }
        }
    return T[N / 3];
}

2 个答案:

答案 0 :(得分:1)

正确的C ++实现如下所示:

$ mkdir django_test cd django_test
$ pipenv shell
(django_test)$ pipenv install django==3.0.5 # change the version you are using
(django_test)$ django-admin startproject .

答案 1 :(得分:0)

首先,返回值应为T [N / 3] [N / 3]。

T [i] [j]表示是否可以得到总和为i的第一个分区和总计为j的第二个分区。显然,由于所有n个数之和为N.所以T [i] [j]为真意味着数组可以分为三个分区,其中和分别为i,j和N-i-j。

最初,T [0] [0]为真且所有其他都为假,这意味着在开始时,只能将数字划分为三个分区:0,0和N. for循环迭代所有n个数字,每次,数字C [i]可以分组到第一个分区或第二个分区。这就是设置T [j + C [i]] [k]和T [j] [k + C [i]]为真的原因。

变量j和k从N开始并递减的原因是,为了避免多次计算单个数。以这种方式考虑:例如,如果j从0开始到N,则T [j] [k],T [j + C [i]] [k],T [j + C [i] * 2] [k],...,T [j + C [i] * x] [k]都将设为true,这是不正确的。你可以简单地选择一个小案例来尝试自己模拟这个过程。