简体   繁体   中英

Dynamic Programming solution for a Recursion solution

Given an input n , find the sum of all the possible combinations of numbers 1 ... n . For example, if n=3 , then all the possible combinations are

(1),(2),(3),(1,2),(1,3),(2,3),(1,2,3)

and their sum is

1 + 2 + 3 + (1+2) + (1+3) + (2+3) + (1+2+3) =24

I am able to solve this problem using recursion . How can I solve this problem using Dynamic Programming ?

#include<iostream>
using namespace std;
int sum=0,n;
int f(int pos,int s)
{
    if(pos>n)
    {
        return 0;
    }
    else
    {
        for(int i=pos+1;i<=n;++i)
        {
            sum+=s+i;
            f(i,s+i);
        }
    }
}
int main()
{
     cin>>n;
     sum=0;
     f(0,0);
     cout<<sum<<'\n';

    }
}

EDIT Though this problem can be solved in constant time using this series .

But I want to know how this can be done using Dynamic Programming as I am very weak at it.

You do not need to use dynamic programming; you can use simple arithmetic if you want.

The number of cases is 2 ^ n, since each number is either on or off for a given sum.

Each number from 1 to n is used in exactly half of the sums, so each number comes 2 ^ (n-1) times. 1 + 2 + ... + n = (n - 1) * n / 2.

So the sum is (n - 1) * n / 2 * 2 ^ (n-1). For n = 3, it is (4*3/2) * 4 = 24.

EDIT : if you really want to use dynamic programming, here's one way. Dynamic programming makes use of saving the results of sub-problems to make the super problem faster to solve. In this question, the sub-problem would be the sum of all combinations from 1 ... n-1.

So create a mapping from n -> (number of combinations, sum of combinations).

Initialize with 1 -> (2,1). Because there are two combinations {0,1} and the sum is 1. Including 0 just makes the math a bit easier.

Then your iteration step is to use the mapping.

Let's say (n-1) -> (k,s), meaning there are k sets that sum to s for 1 ... n-1.

Then the number of sets for n is k * 2 (each combination either has n or does not). And the sum of all combinations is s + (s + k * n), since you have the previous sum (where n is missing) plus the sum of all the combinations with n (which should be k * n more than s because there are k new combinations with n in each).

So add n -> (2*k,2*s + k*n).

And your final answer is the s in n -> (k,s).

let dp[n] be the result, Therefore:

dp[1] = 1
dp[n] = 2 * dp[n-1] + 2^(n-1) * n

First, it is obvious that dp[1] = 1

Second, dp[n] is the sum which contains n and sum which didn't contains n

EG: dp[3] = {(1) (2) (1,2)} + {(3), (1,3), (2,3), (1,2,3)}

We can find dp[n-1] appear twice and the number of n appear 2^(n-1) times

I think maybe it is what you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM