Given two numbers
Examples:
Input : a = 4, m = 4
Output : 2 –> ({4}, {3, 1})
Note: {2, 2} is not a valid set as values are not in decreasing orderInput : a = 7, m = 5
Output : 5 –> ({7}, {6, 1}, {5, 2}, {4, 3}, {4, 2, 1})
Approach: This problem can be solved by Divide and Conquer using a recursive approach which follows the following conditions:
- If a is equal to zero, one solution has been found.
- If a > 0 and m == 0, this set violates the condition as no further values can be added in the set.
- If calculation has already been done for given values of a, m and prev (last value included in the current set), return that value.
- Start a loop from i = a till 0 and if i < prev, count the number of solutions if we include i in the current set and return it.
Below is the implementation of the above approach:
// C++ code to calculate the number of ways // in which a given number can be represented // as set of finite numbers #include <bits/stdc++.h> #include <unordered_map> using namespace std;
// Initialize dictionary which is used // to check if given solution is already // visited or not to avoid // calculating it again unordered_map<string, bool > visited;
// Initialize dictionary which is used to // store the number of ways in which solution // can be obtained for given values unordered_map<string, int > numWays;
// This function returns the total number // of sets which satisfy given criteria // a --> number to be divided into sets // m --> maximum possible size of the set // x --> previously selected value int countNumOfWays( int a, int m, int prev)
{ // number is divided properly and
// hence solution is obtained
if (a == 0)
return 1;
// Solution can't be obtained
if (a > 0 && m == 0)
return 0;
// Return the solution if it has
// already been calculated
string key = to_string(a) + "|" + to_string(m) + "|" + to_string(prev);
if (visited.find(key) != visited.end())
return numWays[key];
visited[key] = true ;
for ( int i = a; i >= 0; i--)
{
// Continue only if current value is
// smaller compared to previous value
if (i < prev)
numWays[key] += countNumOfWays(a - i, m - 1, i);
}
return numWays[key];
} // Values of 'a' and 'm' for which // solution is to be found int a = 7, m = 5, MAX_CONST = 10e5;
// Driver code int main()
{ cout << countNumOfWays(a, m, MAX_CONST) << endl;
return 0;
} |
# Python3 code to calculate the number of ways # in which a given number can be represented # as set of finite numbers # Import function to initialize the dictionary from collections import defaultdict
# Initialize dictionary which is used # to check if given solution is already # visited or not to avoid # calculating it again visited = defaultdict( lambda : False )
# Initialize dictionary which is used to # store the number of ways in which solution # can be obtained for given values numWays = defaultdict( lambda : 0 )
# This function returns the total number # of sets which satisfy given criteria # a --> number to be divided into sets # m --> maximum possible size of the set # x --> previously selected value def countNumOfWays(a, m, prev):
# number is divided properly and
# hence solution is obtained
if a = = 0 :
return 1
# Solution can't be obtained
elif a > 0 and m = = 0 :
return 0
# Return the solution if it has
# already been calculated
elif visited[(a, m, prev)] = = True :
return numWays[(a, m, prev)]
else :
visited[(a, m, prev)] = True
for i in range (a, - 1 , - 1 ):
# Continue only if current value is
# smaller compared to previous value
if i < prev:
numWays[(a, m, prev)] + = countNumOfWays(a - i, m - 1 , i)
return numWays[(a, m, prev)]
# Values of 'a' and 'm' for which # solution is to be found # MAX_CONST is extremely large value # used for first comparison in the function a, m, MAX_CONST = 7 , 5 , 10 * * 5
print (countNumOfWays(a, m, MAX_CONST))
|
// Javascript code to calculate the number of ways // in which a given number can be represented // as set of finite numbers // Import function to initialize the dictionary const visited = new Map();
const numWays = new Map();
// This function returns the total number // of sets which satisfy given criteria // a --> number to be divided into sets // m --> maximum possible size of the set // x --> previously selected value function countNumOfWays(a, m, prev) {
// number is divided properly and
// hence solution is obtained
if (a == 0) {
return 1;
}
// Solution can't be obtained
else if (a > 0 && m == 0) {
return 0;
}
// Return the solution if it has
// already been calculated
else if (visited.has([a, m, prev])) {
return numWays.get([a, m, prev]);
} else {
visited.set([a, m, prev], true );
let totalWays = 0;
for (let i = a; i >= 0; i--) {
// Continue only if current value is
// smaller compared to previous value
if (i < prev) {
totalWays += countNumOfWays(a - i, m - 1, i);
}
}
numWays.set([a, m, prev], totalWays);
return totalWays;
}
} // Values of 'a' and 'm' for which // solution is to be found // MAX_CONST is extremely large value // used for first comparison in the function const a = 7, m = 5,
MAX_CONST = 10 ** 5;
console.log(countNumOfWays(a, m, MAX_CONST)); |
import java.util.*;
public class Main {
// Initialize dictionary which is used
// to check if given solution is already
// visited or not to avoid
// calculating it again
static Map<String, Boolean> visited = new HashMap<>();
// Initialize dictionary which is used to
// store the number of ways in which solution
// can be obtained for given values
static Map<String, Integer> numWays = new HashMap<>();
// This function returns the total number
// of sets which satisfy given criteria
// a --> number to be divided into sets
// m --> maximum possible size of the set
// x --> previously selected value
static int countNumOfWays( int a, int m, int prev)
{
// number is divided properly and
// hence solution is obtained
if (a == 0 )
return 1 ;
// Solution can't be obtained
if (a > 0 && m == 0 )
return 0 ;
// Return the solution if it has
// already been calculated
String key = a + "|" + m + "|" + prev;
if (visited.containsKey(key))
return numWays.get(key);
visited.put(key, true );
int ways = 0 ;
for ( int i = a; i >= 0 ; i--)
{
// Continue only if current value is
// smaller compared to previous value
if (i < prev)
ways += countNumOfWays(a - i, m - 1 , i);
}
numWays.put(key, ways);
return ways;
}
// Values of 'a' and 'm' for which
// solution is to be found
static int a = 7 , m = 5 , MAX_CONST = 10 ^ 5 ;
// Driver code
public static void main(String[] args)
{
System.out.println(countNumOfWays(a, m, MAX_CONST));
}
} |
using System;
using System.Collections.Generic;
class GFG
{ // Initialize dictionary which is used
// to check if given solution is already
// visited or not to avoid
// calculating it again
static Dictionary< string , bool > visited = new Dictionary< string , bool >();
// Initialize dictionary which is used to
// store the number of ways in which solution
// can be obtained for given values
static Dictionary< string , int > numWays = new Dictionary< string , int >();
// This function returns the total number
// of sets which satisfy given criteria
// a --> number to be divided into sets
// m --> maximum possible size of the set
// x --> previously selected value
static int CountNumOfWays( int a, int m, int prev)
{
// number is divided properly and
// hence solution is obtained
if (a == 0)
return 1;
// Solution can't be obtained
if (a > 0 && m == 0)
return 0;
// Return the solution if it has
// already been calculated
string key = a + "|" + m + "|" + prev;
if (visited.ContainsKey(key))
return numWays[key];
visited.Add(key, true );
int ways = 0;
for ( int i = a; i >= 0; i--)
{
// Continue only if current value is
// smaller compared to previous value
if (i < prev)
ways += CountNumOfWays(a - i, m - 1, i);
}
numWays.Add(key, ways);
return ways;
}
// Values of 'a' and 'm' for which
// solution is to be found
static int a = 7, m = 5, MAX_CONST = ( int )Math.Pow(10, 5);
// Driver code
public static void Main( string [] args)
{
Console.WriteLine(CountNumOfWays(a, m, MAX_CONST));
}
} |
5
Time Complexity: O(a*log(a))
Auxiliary Space: O(a)