Given n, how many distinct Max Heap can be made from n distinct integers?
Examples:
Input : n = 3
Output : Assume the integers are 1, 2, 3.
Then the 2 possible max heaps are:       
            3
           / \
          1   2
           3
          / \
         2   1
Input : n = 4
Output : Assume the integers are 1, 2, 3, 4.
Then the 3 possible max heaps are:
        4 
       / \ 
      3   2 
     / 
    1
        4 
       / \ 
      2   3 
     / 
    1
        4 
       / \ 
      3   1 
     / 
    2
Since there is only one element as the root, it must be the largest number. Now we have n-1 remaining elements. The main observation here is that because of the max heap properties, the structure of the heap nodes will remain the same in all instances, but only the values in the nodes will change.
Assume there are l elements in the left sub-tree and r elements in the right sub-tree. Now for the root, l + r = n-1. From this we can see that we can choose any l of the remaining n-1 elements for the left sub-tree as they are all smaller than the root.
We know the there are 
T(n) = 
Now we have to find the values for l and r for a given n. We know that the height of the heap h = 



l = 
(or) the last level is less than half-filled: 
l = 
(we get 

From this we can also say that r = n – l – 1.
We can use the dynamic programming approach discussed in this post here to find the values of 
             T(7)
            /    \
          T(3)   T(3)
         /  \     /  \    
     T(1)  T(1) T(1) T(1) 
Following is the implementation of the above approach:
C++
| // CPP program to count max heaps with n distinct keys#include <iostream>usingnamespacestd;#define MAXN 105 // maximum value of n here// dp[i] = number of max heaps for i distinct integersintdp[MAXN]; // nck[i][j] = number of ways to choose j elements//             form i elements, no order */intnck[MAXN][MAXN]; // log2[i] = floor of logarithm of base 2 of iintlog2[MAXN]; // to calculate nCkintchoose(intn, intk){    if(k > n)        return0;    if(n <= 1)        return1;    if(k == 0)        return1;    if(nck[n][k] != -1)        returnnck[n][k];    intanswer = choose(n - 1, k - 1) + choose(n - 1, k);    nck[n][k] = answer;    returnanswer;}// calculate l for give value of nintgetLeft(intn){    if(n == 1)        return0;    inth = log2[n];    // max number of elements that can be present in the     // hth level of any heap    intnumh = (1 << h); //(2 ^ h)    // number of elements that are actually present in    // last level(hth level)    // (2^h - 1)    intlast = n - ((1 << h) - 1);    // if more than half-filled    if(last >= (numh / 2))        return(1 << h) - 1; // (2^h) - 1    else        return(1 << h) - 1 - ((numh / 2) - last);}// find maximum number of heaps for nintnumberOfHeaps(intn){    if(n <= 1)        return1;    if(dp[n] != -1)        returndp[n];    intleft = getLeft(n);    intans = (choose(n - 1, left) * numberOfHeaps(left)) *                              (numberOfHeaps(n - 1 - left));    dp[n] = ans;    returnans;}// function to initialize arraysintsolve(intn){    for(inti = 0; i <= n; i++)        dp[i] = -1;    for(inti = 0; i <= n; i++)        for(intj = 0; j <= n; j++)            nck[i][j] = -1;    intcurrLog2 = -1;    intcurrPower2 = 1;    // for each power of two find logarithm    for(inti = 1; i <= n; i++) {        if(currPower2 == i) {            currLog2++;            currPower2 *= 2;        }        log2[i] = currLog2;    }    returnnumberOfHeaps(n);}// driver functionintmain(){    intn = 10;    cout << solve(n) << endl;    return0;} | 
Java
| // Java program to count max heaps with n distinct keys importjava.util.*;importjava.io.*;classGFG{    staticintMAXN = 105; // maximum value of n here     // dp[i] = number of max heaps for i distinct integers     staticint[] dp = newint[MAXN];    // nck[i][j] = number of ways to choose j elements     //         form i elements, no order */     staticint[][] nck = newint[MAXN][MAXN];    // log2[i] = floor of logarithm of base 2 of i     staticint[] log2 = newint[MAXN];    // to calculate nCk     publicstaticintchoose(intn, intk)     {        if(k > n)         {            return0;        }        if(n <= 1)         {            return1;        }        if(k == 0)        {            return1;        }        if(nck[n][k] != -1)        {            returnnck[n][k];        }        intanswer = choose(n - 1, k - 1) + choose(n - 1, k);        nck[n][k] = answer;        returnanswer;    }    // calculate l for give value of n     publicstaticintgetLeft(intn)     {        if(n == 1)         {            return0;        }        inth = log2[n];        // max number of elements that can be present in the         // hth level of any heap         intnumh = (1<< h); //(2 ^ h)         // number of elements that are actually present in         // last level(hth level)         // (2^h - 1)         intlast = n - ((1<< h) - 1);        // if more than half-filled         if(last >= (numh / 2))        {            return(1<< h) - 1; // (2^h) - 1         }         else        {            return(1<< h) - 1- ((numh / 2) - last);        }    }    // find maximum number of heaps for n     publicstaticintnumberOfHeaps(intn)     {        if(n <= 1)        {            return1;        }        if(dp[n] != -1)         {            returndp[n];        }        intleft = getLeft(n);        intans = (choose(n - 1, left) * numberOfHeaps(left))                * (numberOfHeaps(n - 1- left));        dp[n] = ans;        returnans;    }    // function to initialize arrays     publicstaticintsolve(intn)    {        for(inti = 0; i <= n; i++)        {            dp[i] = -1;        }        for(inti = 0; i <= n; i++)         {            for(intj = 0; j <= n; j++)            {                nck[i][j] = -1;            }        }        intcurrLog2 = -1;        intcurrPower2 = 1;        // for each power of two find logarithm         for(inti = 1; i <= n; i++)         {            if(currPower2 == i)             {                currLog2++;                currPower2 *= 2;            }            log2[i] = currLog2;        }        returnnumberOfHeaps(n);    }    // Driver code     publicstaticvoidmain(String[] args)     {        intn = 10;        System.out.print(solve(n));    }}// This code has been contributed by 29AjayKumar | 
Python3
| # Python program to count max heaps with n distinct keysMAXN =105# maximum value of n here# dp[i] = number of max heaps for i distinct integersdp =[0]*MAXN# nck[i][j] = number of ways to choose j elements#             form i elements, no order */nck =[[0fori inrange(MAXN)] forj inrange(MAXN)]# log2[i] = floor of logarithm of base 2 of ilog2 =[0]*MAXN# to calculate nCkdefchoose(n, k):    if(k > n):        return0    if(n <=1):        return1    if(k ==0):        return1    if(nck[n][k] !=-1):        returnnck[n][k]    answer =choose(n -1, k -1) +choose(n -1, k)    nck[n][k] =answer    returnanswer# calculate l for give value of ndefgetLeft(n):    if(n ==1):        return0    h =log2[n]    # max number of elements that can be present in the     # hth level of any heap    numh =(1<< h) #(2 ^ h)    # number of elements that are actually present in    # last level(hth level)    # (2^h - 1)    last =n -((1<< h) -1)    # if more than half-filled    if(last >=(numh //2)):        return(1<< h) -1# (2^h) - 1    else:        return(1<< h) -1-((numh //2) -last)# find maximum number of heaps for ndefnumberOfHeaps(n):    if(n <=1):        return1    if(dp[n] !=-1):        returndp[n]    left =getLeft(n)    ans =(choose(n -1, left) *numberOfHeaps(left)) *(numberOfHeaps(n -1-left))    dp[n] =ans    returnans# function to initialize arraysdefsolve(n):    fori inrange(n+1):        dp[i] =-1    fori inrange(n+1):        forj inrange(n+1):            nck[i][j] =-1    currLog2 =-1    currPower2 =1    # for each power of two find logarithm    fori inrange(1,n+1):        if(currPower2 ==i):            currLog2 +=1            currPower2 *=2        log2[i] =currLog2    returnnumberOfHeaps(n)# Driver coden =10print(solve(n))# This code is contributed by ankush_953 | 
C#
| // C# program to count max heaps with n distinct keys usingSystem;   classGFG {     staticintMAXN = 105; // maximum value of n here           // dp[i] = number of max heaps for i distinct integers     staticint[] dp = newint[MAXN];            // nck[i][j] = number of ways to choose j elements     //             form i elements, no order */     staticint[,] nck = newint[MAXN,MAXN];            // log2[i] = floor of logarithm of base 2 of i     staticint[] log2 = newint[MAXN];            // to calculate nCk     publicstaticintchoose(intn, intk)     {         if(k > n)             return0;         if(n <= 1)             return1;         if(k == 0)             return1;               if(nck[n,k] != -1)             returnnck[n,k];               intanswer = choose(n - 1, k - 1) + choose(n - 1, k);         nck[n,k] = answer;         returnanswer;     }           // calculate l for give value of n     publicstaticintgetLeft(intn)     {         if(n == 1)             return0;               inth = log2[n];               // max number of elements that can be present in the          // hth level of any heap         intnumh = (1 << h); //(2 ^ h)               // number of elements that are actually present in         // last level(hth level)         // (2^h - 1)         intlast = n - ((1 << h) - 1);               // if more than half-filled         if(last >= (numh / 2))             return(1 << h) - 1; // (2^h) - 1         else            return(1 << h) - 1 - ((numh / 2) - last);     }           // find maximum number of heaps for n     publicstaticintnumberOfHeaps(intn)     {         if(n <= 1)             return1;               if(dp[n] != -1)             returndp[n];               intleft = getLeft(n);         intans = (choose(n - 1, left) * numberOfHeaps(left)) *                                   (numberOfHeaps(n - 1 - left));         dp[n] = ans;         returnans;     }           // function to initialize arrays     publicstaticintsolve(intn)     {         for(inti = 0; i <= n; i++)             dp[i] = -1;               for(inti = 0; i <= n; i++)             for(intj = 0; j <= n; j++)                 nck[i,j] = -1;               intcurrLog2 = -1;         intcurrPower2 = 1;               // for each power of two find logarithm         for(inti = 1; i <= n; i++) {             if(currPower2 == i) {                 currLog2++;                 currPower2 *= 2;             }             log2[i] = currLog2;         }               returnnumberOfHeaps(n);     }           // driver function     staticvoidMain()     {         intn = 10;         Console.Write(solve(n));     }    //This code is contributed by DrRoot_} | 
Javascript
| <script>// JavaScript program to count max heaps with n distinct keys let MAXN = 105; // maximum value of n here // dp[i] = number of max heaps for i distinct integers let dp = newArray(MAXN);// nck[i][j] = number of ways to choose j elements     //         form i elements, no order */let nck = newArray(MAXN);for(let i=0;i<MAXN;i++){    nck[i]=newArray(MAXN);    for(let j=0;j<MAXN;j++)        nck[i][j]=0;}// log2[i] = floor of logarithm of base 2 of i let log2 = newArray(MAXN); // to calculate nCk functionchoose(n,k){    if(k > n)         {            return0;        }        if(n <= 1)         {            return1;        }        if(k == 0)        {            return1;        }          if(nck[n][k] != -1)        {            returnnck[n][k];        }          let answer = choose(n - 1, k - 1) + choose(n - 1, k);        nck[n][k] = answer;        returnanswer;} // calculate l for give value of nfunctiongetLeft(n){    if(n == 1)         {            return0;        }          let h = log2[n];          // max number of elements that can be present in the         // hth level of any heap         let numh = (1 << h); //(2 ^ h)           // number of elements that are actually present in         // last level(hth level)         // (2^h - 1)         let last = n - ((1 << h) - 1);          // if more than half-filled         if(last >= (numh / 2))        {            return(1 << h) - 1; // (2^h) - 1         }         else        {            return(1 << h) - 1 - ((numh / 2) - last);        }}// find maximum number of heaps for n functionnumberOfHeaps(n){    if(n <= 1)        {            return1;        }          if(dp[n] != -1)         {            returndp[n];        }          let left = getLeft(n);        let ans = (choose(n - 1, left) * numberOfHeaps(left))                * (numberOfHeaps(n - 1 - left));        dp[n] = ans;        returnans;}// function to initialize arrays functionsolve(n){    for(let i = 0; i <= n; i++)        {            dp[i] = -1;        }          for(let i = 0; i <= n; i++)         {            for(let j = 0; j <= n; j++)            {                nck[i][j] = -1;            }        }          let currLog2 = -1;        let currPower2 = 1;          // for each power of two find logarithm         for(let i = 1; i <= n; i++)         {            if(currPower2 == i)             {                currLog2++;                currPower2 *= 2;            }            log2[i] = currLog2;        }          returnnumberOfHeaps(n);}// Driver code let n = 10;document.write(solve(n));// This code is contributed by rag2127</script> | 
3360
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!


 
                                    







