Given an integer N, the task is to count the number of ways to represent N as the sum of powers of 2.
Examples:
Input: N = 4
Output: 4
Explanation: All possible ways to obtains sum N using powers of 2 are {4, 2+2, 1+1+1+1, 2+1+1}.Input: N = 5
Output: 4
Explanation: All possible ways to obtains sum N using powers of 2 are {4 + 1, 2+2 + 1, 1+1+1+1 + 1, 2+1+1 + 1}
Naive Approach: The simplest approach to solve the problem is to generate all powers of 2 whose values are less than N and print all combinations to represent the sum N.
Efficient Approach: To optimize the above approach, the idea is to use recursion. Define a function f(N, K) which represents the number of ways to express N as a sum of powers of 2 with all the numbers having power less than or equal to k where K ( = log2(N)) is the maximum power of 2 which satisfies 2K ?N.
If (power(2, K) ? N) :
f(N, K) = f(N – power(2, K), K) + f(N, K – 1) //to check if power(2, k) can be one of the number.
Otherwise:
f(N, K)=f(N, K – 1)
Base cases :
- If (N = 0) f(N, K)=1 (Only 1 possible way exists to represent N)
- If (k==0) f(N, K)=1 (Only 1 possible way exists to represent N by taking 20)
Below is the implementation of the above approach:
// C++ program for above implementation #include <bits/stdc++.h> using namespace std;
int numberOfWays( int n, int k)
{ // Base Cases
if (n == 0)
return 1;
if (k == 0)
return 1;
// Check if 2^k can be used as
// one of the numbers or not
if (n >= pow (2, k)) {
int curr_val = pow (2, k);
return numberOfWays(n - curr_val, k)
+ numberOfWays(n, k - 1);
}
// Otherwise
else
// Count number of ways to
// N using 2 ^ k - 1
return numberOfWays(n, k - 1);
} // Driver Code int main()
{ int n = 4;
int k = log2(n);
cout << numberOfWays(n, k) << endl;
} |
// Java program to implement // the above approach import java.util.*;
class GFG
{ static int numberOfWays( int n, int k)
{ // Base Cases
if (n == 0 )
return 1 ;
if (k == 0 )
return 1 ;
// Check if 2^k can be used as
// one of the numbers or not
if (n >= ( int )Math.pow( 2 , k))
{
int curr_val = ( int )Math.pow( 2 , k);
return numberOfWays(n - curr_val, k)
+ numberOfWays(n, k - 1 );
}
// Otherwise
else
// Count number of ways to
// N using 2 ^ k - 1
return numberOfWays(n, k - 1 );
} // Driver code public static void main(String[] args)
{ int n = 4 ;
int k = ( int )(Math.log(n) / Math.log( 2 ));
System.out.println(numberOfWays(n, k));
} } // This code is contributed by susmitakundugoaldanga. |
# Python3 program for above implementation from math import log2
def numberOfWays(n, k):
# Base Cases
if (n = = 0 ):
return 1
if (k = = 0 ):
return 1
# Check if 2^k can be used as
# one of the numbers or not
if (n > = pow ( 2 , k)):
curr_val = pow ( 2 , k)
return numberOfWays(n - curr_val, k) + numberOfWays(n, k - 1 )
# Otherwise
else :
# Count number of ways to
# N using 2 ^ k - 1
return numberOfWays(n, k - 1 )
# Driver Code if __name__ = = '__main__' :
n = 4
k = log2(n)
print (numberOfWays(n, k))
# This code is contributed by mohit kumar 29 |
// C# program to implement // the above approach using System;
class GFG
{ static int numberOfWays( int n, int k)
{ // Base Cases
if (n == 0)
return 1;
if (k == 0)
return 1;
// Check if 2^k can be used as
// one of the numbers or not
if (n >= ( int )Math.Pow(2, k))
{
int curr_val = ( int )Math.Pow(2, k);
return numberOfWays(n - curr_val, k)
+ numberOfWays(n, k - 1);
}
// Otherwise
else
// Count number of ways to
// N using 2 ^ k - 1
return numberOfWays(n, k - 1);
} // Driver code public static void Main(String[] args)
{ int n = 4;
int k = ( int )(Math.Log(n) / Math.Log(2));
Console.WriteLine(numberOfWays(n, k));
} } // This code is contributed by 29AjayKumar |
<script> // JavaScript program for above implementation function numberOfWays(n, k)
{ // Base Cases
if (n == 0)
return 1;
if (k == 0)
return 1;
// Check if 2^k can be used as
// one of the numbers or not
if (n >= Math.pow(2, k)) {
let curr_val = Math.pow(2, k);
return numberOfWays(n - curr_val, k)
+ numberOfWays(n, k - 1);
}
// Otherwise
else
// Count number of ways to
// N using 2 ^ k - 1
return numberOfWays(n, k - 1);
} // Driver Code let n = 4;
let k = Math.log2(n);
document.write(numberOfWays(n, k) + "<br>" );
// This code is contributed by Mayank Tyagi </script> |
4
Time Complexity: O((logN+K)K ), where K is log2(N)
Auxiliary Space: O(1)
Another Efficient Approach ( using DP) : First we iterate all values of power of 2<= N , starting from 1. Then , we will find value of big problem using value of small sub-problems .
Below is the implementation of the above approach:
// C++ program for above implementation #include <bits/stdc++.h> using namespace std;
// Function to count the number of ways to represent // n as the power of 2 int numberOfWays( int n)
{ // Initialize an array dp with size n+1
int dp[n+1] = {0};
// Base case- there is only 1 way to represent 0
// as a sum of powers of 2
dp[0] = 1;
// Iterate all powers of 2 starting from 1
for ( int i = 1; i <= n; i = i*2)
{
// Iterate through all numbers from 1 to n
for ( int j = i; j <= n; j++)
{
// Using sub-problems that is already calculated to find the
// number of ways to represent j as a sum of powers of 2
dp[j] += dp[j-i];
}
}
// Return the number of ways to represent
// n as a sum of powers of 2
return dp[n];
} //Drive code int main() {
int n=4;
//Function call
cout << "Number of ways: " << numberOfWays(n) << endl;
return 0;
} // This code is contributed by nikhilsainiofficial546 |
// Java program for above implementation import java.util.*;
public class Main {
// Function to count the number of ways to represent
// n as the power of 2
static int numberOfWays( int n)
{
// Initialize an array dp with size n+1
int dp[] = new int [n + 1 ];
// Base case- there is only 1 way to represent 0
// as a sum of powers of 2
dp[ 0 ] = 1 ;
// Iterate all powers of 2 starting from 1
for ( int i = 1 ; i <= n; i = i * 2 ) {
// Iterate through all numbers from 1 to n
for ( int j = i; j <= n; j++) {
// Using sub-problems that is already
// calculated to find the number of ways to
// represent j as a sum of powers of 2
dp[j] += dp[j - i];
}
}
// Return the number of ways to represent
// n as a sum of powers of 2
return dp[n];
}
// Drive code
public static void main(String[] args)
{
int n = 4 ;
// Function call
System.out.println( "Number of ways: "
+ numberOfWays(n));
}
} |
# Python3 program for above implementation # Function to count the number of ways to represent # n as the power of 2 def numberOfWays(n):
# Initialize an array dp with size n+1
dp = [ 0 for i in range (n + 1 )]
# Base case- there is only 1 way to represent 0
# as a sum of powers of 2
dp[ 0 ] = 1
# Iterate all powers of 2 starting from 1
i = 1
while i < = n:
# Iterate through all numbers from 1 to n
j = i
while j < = n:
# Using sub-problems that is already calculated to find the
# number of ways to represent j as a sum of powers of 2
dp[j] + = dp[j - i]
j + = 1
i * = 2
# Return the number of ways to represent
# n as a sum of powers of 2
return dp[n]
# Drive code if __name__ = = '__main__' :
n = 4
# Function call
print ( "Number of ways:" , numberOfWays(n))
# This code is contributed by nikhilsainiofficial546 |
// C# program for the above approach using System;
public class GFG
{ // Function to count the number of ways to represent
// n as the power of 2
static int NumberOfWays( int n)
{
// Initialize an array dp with size n+1
int [] dp = new int [n + 1];
// Base case- there is only 1 way to represent 0
// as a sum of powers of 2
dp[0] = 1;
// Iterate all powers of 2 starting from 1
for ( int i = 1; i <= n; i = i * 2)
{
// Iterate through all numbers from 1 to n
for ( int j = i; j <= n; j++)
{
// Using sub-problems that is already
// calculated to find the number of ways to
// represent j as a sum of powers of 2
dp[j] += dp[j - i];
}
}
// Return the number of ways to represent
// n as a sum of powers of 2
return dp[n];
}
// Drive code
public static void Main( string [] args)
{
int n = 4;
// Function call
Console.WriteLine( "Number of ways: " + NumberOfWays(n));
}
} // This code is contributed by sdeadityasharma |
// Function to count the number of ways to represent // n as the power of 2 function numberOfWays(n) {
// Initialize an array dp with size n+1
let dp = new Array(n+1).fill(0);
// Base case- there is only 1 way to represent 0
// as a sum of powers of 2
dp[0] = 1;
// Iterate all powers of 2 starting from 1
let i = 1;
while (i <= n) {
// Iterate through all numbers from 1 to n
let j = i;
while (j <= n) {
// Using sub-problems that is already calculated to find the
// number of ways to represent j as a sum of powers of 2
dp[j] += dp[j-i];
j += 1;
}
i *= 2;
}
// Return the number of ways to represent
// n as a sum of powers of 2
return dp[n];
} // Driver code let n = 4; // Function call console.log( "Number of ways:" , numberOfWays(n));
|
Number of ways: 4
Time Complexity: O(N*logN), logN time to iterate all powers of 2 that is <=N
Auxiliary Space: O(N)