给定n,可以从n个不同的整数中制作多少个不同的Max Heap?
例子:
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
由于只有一个元素作为根,因此它必须是最大数目。现在我们还有n-1个剩余元素。此处的主要观察结果是,由于具有最大堆属性,所以堆节点的结构在所有实例中都将保持不变,但是只有节点中的值会更改。
假设有在右子树的左子树和R元素L型元件。现在对于根,l + r = n-1。由此可见,我们可以为左子树选择其余n-1个元素中的任意一个,因为它们都比根小。
我们知道有做到这一点的方法。接下来,对于这些实例的每个实例,我们可以具有带有l元素的许多堆,对于每个实例,我们可以具有带有r元素的许多堆。因此,我们可以把它们看成子问题和复发为最终的答案:
T(n)= * T(L)* T(R)。
现在我们必须找到给定n的l和r的值。我们知道堆的高度h = 。也是任何堆的第h个层中可以存在的最大元素数,m = ,其中根位于第0级。此外,堆最后一级实际存在的元素数p = n –( – 1)。 (自从直到倒数第二级为止的节点数)。因此,可能有两种情况:当最后一个级别大于或等于一半填充时:
l = – 1,如果p> = m / 2
(或)最后一级未满一半:
l = – 1 –(((m / 2)– p),如果p
由此我们也可以说r = n – l – 1。
我们可以使用本文中讨论的动态编程方法来找到 。类似地,如果我们查看上面形成的最佳子结构递归的递归树,我们会发现它也具有重叠的子问题属性,因此可以使用动态编程来解决:
T(7)
/ \
T(3) T(3)
/ \ / \
T(1) T(1) T(1) T(1)
以下是上述方法的实现:
C++
// CPP program to count max heaps with n distinct keys
#include
using namespace std;
#define MAXN 105 // maximum value of n here
// dp[i] = number of max heaps for i distinct integers
int dp[MAXN];
// nck[i][j] = number of ways to choose j elements
// form i elements, no order */
int nck[MAXN][MAXN];
// log2[i] = floor of logarithm of base 2 of i
int log2[MAXN];
// to calculate nCk
int choose(int n, int k)
{
if (k > n)
return 0;
if (n <= 1)
return 1;
if (k == 0)
return 1;
if (nck[n][k] != -1)
return nck[n][k];
int answer = choose(n - 1, k - 1) + choose(n - 1, k);
nck[n][k] = answer;
return answer;
}
// calculate l for give value of n
int getLeft(int n)
{
if (n == 1)
return 0;
int h = log2[n];
// max number of elements that can be present in the
// hth level of any heap
int numh = (1 << h); //(2 ^ h)
// number of elements that are actually present in
// last level(hth level)
// (2^h - 1)
int 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
int numberOfHeaps(int n)
{
if (n <= 1)
return 1;
if (dp[n] != -1)
return dp[n];
int left = getLeft(n);
int ans = (choose(n - 1, left) * numberOfHeaps(left)) *
(numberOfHeaps(n - 1 - left));
dp[n] = ans;
return ans;
}
// function to initialize arrays
int solve(int n)
{
for (int i = 0; i <= n; i++)
dp[i] = -1;
for (int i = 0; i <= n; i++)
for (int j = 0; j <= n; j++)
nck[i][j] = -1;
int currLog2 = -1;
int currPower2 = 1;
// for each power of two find logarithm
for (int i = 1; i <= n; i++) {
if (currPower2 == i) {
currLog2++;
currPower2 *= 2;
}
log2[i] = currLog2;
}
return numberOfHeaps(n);
}
// driver function
int main()
{
int n = 10;
cout << solve(n) << endl;
return 0;
}
Java
// Java program to count max heaps with n distinct keys
class GFG
{
static int MAXN = 105; // maximum value of n here
// dp[i] = number of max heaps for i distinct integers
static int[] dp = new int[MAXN];
// nck[i][j] = number of ways to choose j elements
// form i elements, no order */
static int[][] nck = new int[MAXN][MAXN];
// log2[i] = floor of logarithm of base 2 of i
static int[] log2 = new int[MAXN];
// to calculate nCk
public static int choose(int n, int k)
{
if (k > n)
{
return 0;
}
if (n <= 1)
{
return 1;
}
if (k == 0)
{
return 1;
}
if (nck[n][k] != -1)
{
return nck[n][k];
}
int answer = choose(n - 1, k - 1) + choose(n - 1, k);
nck[n][k] = answer;
return answer;
}
// calculate l for give value of n
public static int getLeft(int n)
{
if (n == 1)
{
return 0;
}
int h = log2[n];
// max number of elements that can be present in the
// hth level of any heap
int numh = (1 << h); //(2 ^ h)
// number of elements that are actually present in
// last level(hth level)
// (2^h - 1)
int 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
public static int numberOfHeaps(int n)
{
if (n <= 1)
{
return 1;
}
if (dp[n] != -1)
{
return dp[n];
}
int left = getLeft(n);
int ans = (choose(n - 1, left) * numberOfHeaps(left))
* (numberOfHeaps(n - 1 - left));
dp[n] = ans;
return ans;
}
// function to initialize arrays
public static int solve(int n)
{
for (int i = 0; i <= n; i++)
{
dp[i] = -1;
}
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= n; j++)
{
nck[i][j] = -1;
}
}
int currLog2 = -1;
int currPower2 = 1;
// for each power of two find logarithm
for (int i = 1; i <= n; i++)
{
if (currPower2 == i)
{
currLog2++;
currPower2 *= 2;
}
log2[i] = currLog2;
}
return numberOfHeaps(n);
}
// Driver code
public static void main(String[] args)
{
int n = 10;
System.out.print(solve(n));
}
}
// This code has been contributed by 29AjayKumar
Python3
# Python program to count max heaps with n distinct keys
MAXN = 105 # maximum value of n here
# dp[i] = number of max heaps for i distinct integers
dp = [0]*MAXN
# nck[i][j] = number of ways to choose j elements
# form i elements, no order */
nck = [[0 for i in range(MAXN)] for j in range(MAXN)]
# log2[i] = floor of logarithm of base 2 of i
log2 = [0]*MAXN
# to calculate nCk
def choose(n, k):
if (k > n):
return 0
if (n <= 1):
return 1
if (k == 0):
return 1
if (nck[n][k] != -1):
return nck[n][k]
answer = choose(n - 1, k - 1) + choose(n - 1, k)
nck[n][k] = answer
return answer
# calculate l for give value of n
def getLeft(n):
if (n == 1):
return 0
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 n
def numberOfHeaps(n):
if (n <= 1):
return 1
if (dp[n] != -1):
return dp[n]
left = getLeft(n)
ans = (choose(n - 1, left) * numberOfHeaps(left)) * (numberOfHeaps(n - 1 - left))
dp[n] = ans
return ans
# function to initialize arrays
def solve(n):
for i in range(n+1):
dp[i] = -1
for i in range(n+1):
for j in range(n+1):
nck[i][j] = -1
currLog2 = -1
currPower2 = 1
# for each power of two find logarithm
for i in range(1,n+1):
if (currPower2 == i):
currLog2 += 1
currPower2 *= 2
log2[i] = currLog2
return numberOfHeaps(n)
# Driver code
n = 10
print(solve(n))
# This code is contributed by ankush_953
C#
// C# program to count max heaps with n distinct keys
using System;
class GFG
{
static int MAXN = 105; // maximum value of n here
// dp[i] = number of max heaps for i distinct integers
static int[] dp = new int[MAXN];
// nck[i][j] = number of ways to choose j elements
// form i elements, no order */
static int[,] nck = new int[MAXN,MAXN];
// log2[i] = floor of logarithm of base 2 of i
static int[] log2 = new int[MAXN];
// to calculate nCk
public static int choose(int n, int k)
{
if (k > n)
return 0;
if (n <= 1)
return 1;
if (k == 0)
return 1;
if (nck[n,k] != -1)
return nck[n,k];
int answer = choose(n - 1, k - 1) + choose(n - 1, k);
nck[n,k] = answer;
return answer;
}
// calculate l for give value of n
public static int getLeft(int n)
{
if (n == 1)
return 0;
int h = log2[n];
// max number of elements that can be present in the
// hth level of any heap
int numh = (1 << h); //(2 ^ h)
// number of elements that are actually present in
// last level(hth level)
// (2^h - 1)
int 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
public static int numberOfHeaps(int n)
{
if (n <= 1)
return 1;
if (dp[n] != -1)
return dp[n];
int left = getLeft(n);
int ans = (choose(n - 1, left) * numberOfHeaps(left)) *
(numberOfHeaps(n - 1 - left));
dp[n] = ans;
return ans;
}
// function to initialize arrays
public static int solve(int n)
{
for (int i = 0; i <= n; i++)
dp[i] = -1;
for (int i = 0; i <= n; i++)
for (int j = 0; j <= n; j++)
nck[i,j] = -1;
int currLog2 = -1;
int currPower2 = 1;
// for each power of two find logarithm
for (int i = 1; i <= n; i++) {
if (currPower2 == i) {
currLog2++;
currPower2 *= 2;
}
log2[i] = currLog2;
}
return numberOfHeaps(n);
}
// driver function
static void Main()
{
int n = 10;
Console.Write(solve(n));
}
//This code is contributed by DrRoot_
}
输出:
3360