Count all unique outcomes possible by performing S flips on N coins - GeeksforGeeks

11 Jun, 2021
Given two positive integers N and S, the task is to count the number of unique outcomes possible when S flip operations are performed on N coins.
Examples:
Input: N = 3, S = 4Output: 3Explanation: Considering the initial configuration of coins to be “HHH”, then the possible combinations of 4 flips are:
Flipping the 1st and 2nd coins once and the third coin twice modifies the configuration to “TTH”.Flipping the 1st and 3rd coins once and the 2nd coin twice modifies the configuration to “THT”.Flipping the 2nd and 3rd coins once and the 1st coin twice modifies the configuration to “HTT”.
Flipping the 1st and 2nd coins once and the third coin twice modifies the configuration to “TTH”.
Flipping the 1st and 3rd coins once and the 2nd coin twice modifies the configuration to “THT”.
Flipping the 2nd and 3rd coins once and the 1st coin twice modifies the configuration to “HTT”.
The above three combinations are unique. Therefore, the total count is 3.
Input: N = 3, S = 6Output: 4
Naive Approach: The given problem can be solved by using recursion whose recursive state is defined as:
Consider F(N, S) represents the number of unique outcomes when N coins are tossed with the total number of flips equals to S.
Then F(N, S) can also be expressed as the sum of all combinations with 1 flip or 2 flips i.e.,
F(N, S) = F(N – 1, S – 1) + F(N – 1, S – 2)
The base case for this recurrence relation is F(K, K) whose value is 1 for all (K > 1).
Below is the table that shows the distribution of F(N, S) = F(N – 1, S – 1) + F(N – 1, S – 2), where F(K, K) = 1.
Follow the below steps to solve the problem:
Declare a function, say numberOfUniqueOutcomes(N, S) that takes the number of coins and flips allowed as the parameters respectively and perform the following steps:If the value of S is less than N, then return 0 from the function.If the value of N is S or 1, then return 1 from the function as this is one of the unique combinations.Recursively return summation of the two recursive states as:
If the value of S is less than N, then return 0 from the function.
If the value of N is S or 1, then return 1 from the function as this is one of the unique combinations.
Recursively return summation of the two recursive states as:
return numberOfUniqueOutcomes(N – 1, S – 1) + numberOfUniqueOutcomes(N – 1, S – 2)
After completing the above steps, print the value returned by the function numberOfUniqueOutcomes(N, S) as the resultant number of outcomes.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // Function to recursively count the// number of unique outcomes possible// S flips are performed on N coinsint numberOfUniqueOutcomes(int N, int S){    // Base Cases    if (S < N)        return 0;    if (N == 1 || N == S)        return 1;     // Recursive Calls    return (numberOfUniqueOutcomes(N - 1, S - 1)            + numberOfUniqueOutcomes(N - 1, S - 2));} // Driver Codeint main(){    int N = 3, S = 4;     cout << numberOfUniqueOutcomes(N, S);     return 0;}
// Java program for the above approachimport java.io.*;class GFG{   // Function to recursively count the  // number of unique outcomes possible  // S flips are performed on N coins  static int numberOfUniqueOutcomes(int N, int S)  {     // Base Cases    if (S < N)      return 0;    if (N == 1 || N == S)      return 1;     // Recursive Calls    return (numberOfUniqueOutcomes(N - 1, S - 1)            + numberOfUniqueOutcomes(N - 1, S - 2));  }   // Driver Code  public static void main (String[] args)  {    int N = 3, S = 4;    System.out.println(numberOfUniqueOutcomes(N, S));  }} //  This code is contributed by avanitrachhadiya2155
# Python3 program for the above approach # Function to recursively count the# number of unique outcomes possible# S flips are performed on N coinsdef numberOfUniqueOutcomes(N, S):         # Base Cases    if (S < N):        return 0    if (N == 1 or N == S):        return 1     # Recursive Calls    return (numberOfUniqueOutcomes(N - 1, S - 1) +            numberOfUniqueOutcomes(N - 1, S - 2)) # Driver Codeif __name__ == '__main__':         N, S = 3, 4     print (numberOfUniqueOutcomes(N, S)) # This code is contributed by mohit kumar 29
// C# program for the above approachusing System; class GFG{ // Function to recursively count the// number of unique outcomes possible// S flips are performed on N coinsstatic int numberOfUniqueOutcomes(int N, int S){         // Base Cases    if (S < N)        return 0;    if (N == 1 || N == S)        return 1;         // Recursive Calls    return (numberOfUniqueOutcomes(N - 1, S - 1) +            numberOfUniqueOutcomes(N - 1, S - 2));} // Driver Codestatic public void Main(){    int N = 3, S = 4;         Console.WriteLine(numberOfUniqueOutcomes(N, S));}} // This code is contributed by sanjoy_62
<script>        // Javascript program for the above approach         // Function to recursively count the        // number of unique outcomes possible        // S flips are performed on N coins        function numberOfUniqueOutcomes(N, S) {            // Base Cases            if (S < N)                return 0;            if (N == 1 || N == S)                return 1;             // Recursive Calls            return (numberOfUniqueOutcomes(N - 1, S - 1)                + numberOfUniqueOutcomes(N - 1, S - 2));        }         // Driver Code         let N = 3, S = 4;         document.write(numberOfUniqueOutcomes(N, S))         // This code is contributed by Hritik    </script>
3
 
Time Complexity: O(2N)Auxiliary Space: O(N)
Efficient Approach: The above approach can also be optimized by storing the recursive states as it contains overlapping subproblems. Therefore, the idea is to use memoization to store the repeated states. Follow the steps below to solve the problem:
Initialize a 2D array, say dp[][] of dimensions N*M such that dp[i][j] stores the number of possible outcomes using i coins and j number of flips.
Declare a function, say numberOfUniqueOutcomes(N, S), that takes the number of coins and flips allowed as the parameters respectively and perform the following steps:If the value of S is less than N, then update the value of dp[N][S] as 0 and return this value from the function.If the value of N is S or 1, then update the value of dp[N][S] as 1 and return this value from the function as this is one of the unique combinations.If the value of dp[N][S] is already calculated, then return the value dp[N][S] from the function.Recursively update the value of dp[N][S] summation of the two recursive states as shown below and return this value from the function.
If the value of S is less than N, then update the value of dp[N][S] as 0 and return this value from the function.
If the value of N is S or 1, then update the value of dp[N][S] as 1 and return this value from the function as this is one of the unique combinations.
If the value of dp[N][S] is already calculated, then return the value dp[N][S] from the function.
Recursively update the value of dp[N][S] summation of the two recursive states as shown below and return this value from the function.
dp[N][S] = numberOfUniqueOutcomes(N – 1, S – 1) + numberOfUniqueOutcomes(N – 1, S – 2)
After completing the above steps, print the value returned by the function numberOfUniqueOutcomes(N, S) as the resultant number of outcomes.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for the above approach #include <bits/stdc++.h>using namespace std; // Dimensions of the DP table#define size 1001 // Stores the dp statesint ans[size][size] = { 0 }; // Function to recursively count the// number of unique outcomes possible// by performing S flips on N coinsint numberOfUniqueOutcomes(int n, int s){    // Base Case    if (s < n)        ans[n][s] = 0;     else if (n == 1 || n == s)        ans[n][s] = 1;     // If the count for the current    // state is not calculated, then    // calculate it recursively    else if (!ans[n][s]) {        ans[n][s] = numberOfUniqueOutcomes(n - 1,                                           s - 1)                    + numberOfUniqueOutcomes(n - 1,                                             s - 2);    }     // Otherwise return the    // already calculated value    return ans[n][s];} // Driver Codeint main(){    int N = 5, S = 8;     cout << numberOfUniqueOutcomes(N, S);     return 0;}
// Java program for the above approach import java.util.*; class GFG{   // Dimensions of the DP tablestatic int size = 100;static int [][]ans = new int[size][size];   static void initialize(){     // Stores the dp states  for(int i = 0; i < size; i++)  {    for(int j = 0; j < size; j++)    {        ans[i][j] = 0;    }}} // Function to recursively count the// number of unique outcomes possible// by performing S flips on N coinsstatic int numberOfUniqueOutcomes(int n, int s){    // Base Case    if (s < n)        ans[n][s] = 0;     else if (n == 1 || n == s)        ans[n][s] = 1;     // If the count for the current    // state is not calculated, then    // calculate it recursively    else if (ans[n][s] == 0) {        ans[n][s] = numberOfUniqueOutcomes(n - 1,                                           s - 1)                    + numberOfUniqueOutcomes(n - 1,                                             s - 2);    }     // Otherwise return the    // already calculated value    return ans[n][s];} // Driver Codepublic static void main(String args[]){    initialize();    int N = 5, S = 8;    System.out.println(numberOfUniqueOutcomes(N, S));}} // This code is contributed by SURENDRA_GANGWAR.
# Python3 program for the above approach # Dimensions of the DP tablesize = 100 # Stores the dp statesans = [[0 for i in range(size)]          for j in range(size)] # Function to recursively count the# number of unique outcomes possible# by performing S flips on N coinsdef numberOfUniqueOutcomes(n, s):         # Base Case    if (s < n):        ans[n][s] = 0;         elif (n == 1 or n == s):        ans[n][s] = 1;         # If the count for the current    # state is not calculated, then    # calculate it recursively    elif(ans[n][s] == 0):        ans[n][s] = (numberOfUniqueOutcomes(n - 1, s - 1) +                     numberOfUniqueOutcomes(n - 1, s - 2))         # Otherwise return the    # already calculated value    return ans[n][s]; # Driver CodeN = 5S = 8 print(numberOfUniqueOutcomes(N, S)) # This code is contributed by rag2127
// C# program for the above approachusing System; class GFG{  // Dimensions of the DP tablestatic int size = 100;static int [,]ans = new int[size, size];   static void initialize(){       // Stores the dp states    for(int i = 0; i < size; i++)    {        for(int j = 0; j < size; j++)        {            ans[i, j] = 0;        }    }} // Function to recursively count the// number of unique outcomes possible// by performing S flips on N coinsstatic int numberOfUniqueOutcomes(int n, int s){         // Base Case    if (s < n)        ans[n, s] = 0;     else if (n == 1 || n == s)        ans[n, s] = 1;     // If the count for the current    // state is not calculated, then    // calculate it recursively    else if (ans[n, s] == 0)    {        ans[n, s] = numberOfUniqueOutcomes(n - 1,                                           s - 1) +                    numberOfUniqueOutcomes(n - 1,                                           s - 2);    }     // Otherwise return the    // already calculated value    return ans[n,s];} // Driver Codepublic static void Main(string []args){    initialize();    int N = 5, S = 8;         Console.WriteLine(numberOfUniqueOutcomes(N, S));}} // This code is contributed by AnkThon
<script>     // JavaScript program for the above approach         // Dimensions of the DP table    let size = 100;    let ans = new Array(size);     function initialize()    {       // Stores the dp states      for(let i = 0; i < size; i++)      {          ans[i] = new Array(size);        for(let j = 0; j < size; j++)        {            ans[i][j] = 0;        }      }    }     // Function to recursively count the    // number of unique outcomes possible    // by performing S flips on N coins    function numberOfUniqueOutcomes(n, s)    {        // Base Case        if (s < n)            ans[n][s] = 0;         else if (n == 1 || n == s)            ans[n][s] = 1;         // If the count for the current        // state is not calculated, then        // calculate it recursively        else if (ans[n][s] == 0) {            ans[n][s] = numberOfUniqueOutcomes(n - 1,                                               s - 1)                        + numberOfUniqueOutcomes(n - 1,                                                 s - 2);        }         // Otherwise return the        // already calculated value        return ans[n][s];    }         initialize();    let N = 5, S = 8;    document.write(numberOfUniqueOutcomes(N, S));     </script>
15
 
Time Complexity: O(N*S)Auxiliary Space: O(N*S)
mohit kumar 29
avanitrachhadiya2155
SURENDRA_GANGWAR
sanjoy_62
ankthon
rag2127
hritikrommie
suresh07
Probability
Dynamic Programming
Mathematical
Recursion
Dynamic Programming
Mathematical
Recursion
Probability
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Maximum Subarray Sum using Divide and Conquer algorithm
Optimal Substructure Property in Dynamic Programming | DP-2
Min Cost Path | DP-6
Weighted Job Scheduling
Maximum sum such that no two elements are adjacent
C++ Data Types
Write a program to print all permutations of a given string
Set in C++ Standard Template Library (STL)
Program to find GCD or HCF of two numbers
Merge two sorted arrays