Пожалуйста, прочтите новое правило об ограничении использования AI-инструментов. ×

Блог пользователя SHUVRO.C.DAS

Автор SHUVRO.C.DAS, история, 4 года назад, По-английски

I am currently learning dynamic programming. While writing the code of best sum memoization I am facing a problem.

Problem Statement:

"write a function bestsum(target sum, argument) that takes a target sum and an array of integers as argument. the function should return an array containing the shortest combination of the target sum. we can use an element of the array more than one."

example: input- 10 3 2 3 1

output-
             3 3 2 2

I tried to solve it. it works but takes a lot of time. How to solve it using dp memoization with c++???

*******my code link = https://github.com/Shuvro-d/Dynamic.Programming/blob/main/test%202.cpp

  • Проголосовать: нравится
  • +8
  • Проголосовать: не нравится

»
4 года назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Assume your target sum is quite small say <1e6. For every number you can memorize the best solution, instead of calling bestsum() recursively. (you call the same target sum multiple times and it grows somehow exponentially).

Denote $$$<x,y>$$$ where $$$x$$$ to be the minimum length of array , $$$y$$$ to be the previous number makes your array minimal, Say $$$<5,100>$$$ means the array has 5 elements and the first 4 elements comes from the optimal solution in $$$100$$$

assume input is 10 3 1 3 4, we calculate the best solution from 0 to your desired target.

target sum 0 : []

target sum 1 : 1 + target sum 0 / 3 + target sum -2 / 4 + target sum -3 = 1 + target sum 0 = <1,0>

target sum 2 : <2,1> = [1,1]

target sum 3 : 1 + <2,1> / 3 + <0,0> = <1,0> = [3]

target sum 4 : 1 + <1,3> / 3 + <1,1> / 4 + <0,0> = <1,0> = [4]

target sum 5 : 1 + <1,4> / 3 + <2,1> / 4 + <1,1> = <2,4> / <2,1> = [1,4]

target sum 6 : 1 + <2,5> / 3 + <1,3> / 4 + <2,2> = <2,3> = [3,3]

then 10 = <3,6> = [4] + optimal solution for 6 = [4] + [3] + optimal solution for 3 = [4,3,3]

bool bestsum(int n,int m,int a[]){
    int minlen[n+1];
    int par[n+1];
    memset(minlen,0,sizeof(minlen));
    memset(par,0,sizeof(par));
    for(int i=1;i<=n;i++){
        int l=-1; // if -1 then no solution
        int p=0;
        for(int j=0;j<m;j++){
            int r=i-a[j];
            if(r>=0&&minlen[r]>=0){ // check r has solution or not
                if(l==-1||minlen[r]<l){ // check is optimal or not
                    l=minlen[r]+1;
                    p=r;
                }
            }
        }
        minlen[i]=l;
        par[i]=p;
    }
    if(minlen[n]>=0){
        int r=par[n];
        while(n>0){
            r=par[n];
            save.push_back(n-r);
            n=r;
        }
        flag = true;
    }
    else flag = false;
}
»
12 месяцев назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

For anyone that is still trying to find a pretty simple solution, here you go: ```

include <bits/stdc++.h>

using namespace std;

unordered_map<int, vector> memo;

vector bestSum(int targetSum, const vector& numbers) { if (memo.find(targetSum) != memo.end()) { return memo[targetSum]; }

if (targetSum == 0) {
    return {};
}

if (targetSum < 0) {
    return {INT_MIN};  // Return a sentinel value to represent null
}

vector<int> shortestCombination = {INT_MIN};

for (int num : numbers) {
    int remainder = targetSum - num;
    vector<int> remainderCombination = bestSum(remainder, numbers);

    if (remainderCombination != vector<int>{INT_MIN}) {
        vector<int> combination = remainderCombination;
        combination.push_back(num);

        if (shortestCombination == vector<int>{INT_MIN} || combination.size() < shortestCombination.size()) {
            shortestCombination = combination;
        }
    }
}

memo[targetSum] = shortestCombination;
return shortestCombination;

}

int main() { vector numbers = {1, 2, 5, 25}; int targetSum = 100;

vector<int> result = bestSum(targetSum, numbers);

if (result != vector<int>{INT_MIN}) {
    cout << "Shortest combination: ";
    for (int num : result) {
        cout << num << " ";
    }
    cout << endl;
} else {
    cout << "No valid combination found." << endl;
}

return 0;

} ```