如何在子集和中添加memoization?

时间:2016-10-27 17:24:21

标签: algorithm memoization

我试图用递归解决方案来解决子集求和问题,但是为了使它更有效率,我试图将memoization放入其中。但是,没有memoization的代码会提供正确的解决方案,但是通过memoization它无法正常工作。

public int subsetSum(int num[], int idx, int expecedSum, int dp[]) {
    if (expecedSum == 0) {
        return 1;
    }
    else if (idx < 0 || expecedSum < 0) {
        return 0;
    }
    else {
        if (dp[expecedSum] == -1) {
            int x = subsetSum(num, idx - 1, expecedSum, dp);
            int y = subsetSum(num, idx - 1, expecedSum - num[idx], dp);
            dp[expecedSum] = (x == 1 || y == 1) ? 1 : 0;
        }
        return dp[expecedSum];
    }
} 

public static void main(String args[]) {
    Solution s = new Solution();
    int num[] = new int[]{1, 2, 3, 4, 5, 6, 7};
    int sum = 0;
    int n = new Scanner(System.in).nextInt();
    int dp[] = new int[n + 1];
    for (int i = 0; i < dp.length; i++) {
        dp[i] = -1;
    }

    dp[0] = 1;
    s.subsetSum(num, num.length - 1, n, dp);

}

有人可以帮我解释为什么这不起作用吗?

如果我输入n = 14,那么理想情况下dp [14]应该包含1,但它不包含1.

2 个答案:

答案 0 :(得分:0)

总和不足以描述国家。对(总和,指数)是。如果您使temp <= sum - array[i];数组dp数组并在(max_sum + 1) x num.length方法中对(idx, expectedSum)对应用了memoization,则可行。

答案 1 :(得分:0)

已经好几年了,但是今天可能对某人有所帮助。 想法是同时采用状态-意味着一次将当前元素包括在总和中,一次将当前元素排除在总和中。然后将这些值取OR(||)并存储在缓存中。

代码看起来像这样-

#include <iostream>
#include <vector>
using namespace std;


bool sumExists(vector<int> & a, int cursum, int n, vector<vector<int>> &dp) {
    if(n==0 && cursum != 0)
        return 0;
    
    if(cursum==0)
        return 1;
        
    if(dp[n][cursum] != -1) {
        return dp[n][cursum];
    }
        
    int newsum = cursum - a[n-1];
    
    bool returnval = false;
    
    if(newsum>=0) {
        dp[n][newsum] = sumExists(a, newsum, n-1, dp);
        dp[n][cursum] = sumExists(a, cursum, n-1, dp);
        returnval = dp[n][newsum] || dp[n][cursum];
    } else {
        dp[n][cursum] = sumExists(a, cursum, n-1, dp);
        returnval = dp[n][cursum];
    }
    
    return returnval;
}

int main() {
    // your code goes here
    vector<int> a{2,0,7,8,10};
    int n = a.size();
    
    int sum = 11;
    
    vector<vector<int>> dp(n+1, vector<int>(sum+1, -1));
    
    for(int i=0;i<=n;++i) {
        dp[i][0]=true;
    }
    for(int i=1;i<=sum;++i) {
        dp[0][i]=false;
    }
    
    if(sumExists(a, sum, n, dp)) {
        cout<<"YES"<<endl;
    } else {
        cout<<"NO"<<endl;
    }
}