【问题标题】:Recurrence relation for total number of ways to subset sum子集总和方法总数的递归关系
【发布时间】:2015-07-20 20:06:52
【问题描述】:

我试图找出在子集和问题中达到目标的方法总数。以下是我的方法。

如果“j”个元素的总和等于“i”,则令 DP[i,j] 为 1,否则为 0,其中“a”为输入。所以,

DP[i, j] = DP[i, j-1] + DP[i - a[j], j-1]

对于输入 [10, 13, 15, 18, 20, 15] 和目标 = 30 ;我们正在寻找 DP[30, 6] 作为答案。

我可以使用递归 (http://ideone.com/0sHhDL),但我需要使用 DP。

【问题讨论】:

    标签: algorithm recursion recurrence subset-sum


    【解决方案1】:

    一旦编写了递归函数,我们需要添加的所有内容以使其高效,就是缓存返回值。修改是:在进行递归调用之前,检查这些参数的计算是否尚未完成。

    int NMAX = 100;
    int cache[NMAX][NMAX];
    int answer;
    // Returns true if there is a subset of set[] with sun equal to given sum
    int isSubsetSum(int set[], int n, int sum)
    {
    
        // Base Cases
        if (sum == 0) {
            answer++;
            return 0; //return false here as we are after all the sums
        }
        if (n == 0 && sum != 0)
            return 0;
    
        if(cache[n][sum] == -1) {
    
            // If last element is greater than sum, then ignore it
            if (set[n-1] > sum)
                return isSubsetSum(set, n-1, sum);
    
            /* else, check if sum can be obtained by any of the following
               (a) including the last element
               (b) excluding the last element   */
            cache[n][sum] = isSubsetSum(set, n-1, sum) || isSubsetSum(set, n-1, sum-set[n-1]);
        }
        return cache[n][sum];
    }
    
    // Driver program to test above function
    int main()
    {
        int set[] = {3, 34, 4, 12, 5, 2};
        int sum = 9;
        int n = sizeof(set)/sizeof(set[0]);
        for(int i=0; i<NMAX; i++) for(int j=0; j<NMAX; j++)
            cache[i][j] = -1;
        isSubsetSum(set, n, sum);
        printf("total %d\n", answer);
        return 0;
    }
    

    在代码中,一行

    cache[n][sum] = isSubsetSum(set, n-1, sum) || isSubsetSum(set, n-1, sum-set[n-1]);
    

    等价于递归公式

    DP[i, j] = DP[i, j-1] + DP[i - a[j], j-1]
    

    不同的是,一个是自上而下,一个是自下而上。

    【讨论】:

    • 是的,用sumnset替换ija,这两行是相同的。
    猜你喜欢
    • 1970-01-01
    • 2012-02-19
    • 2020-01-26
    • 2019-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    相关资源
    最近更新 更多