给定一个排序后的数组键[0 … N-1]的搜索键和阵列频率的[0 … N-1]的频率计数,其中频率[i]为搜索到的密钥[I]的数量。构造一个包含所有关键字的二叉搜索树,以使所有搜索的总成本尽可能小。
让我们首先定义BST的成本。 BST节点的成本是该节点的级别乘以其频率。根级别为1。
例子:
Input: keys[] = {10, 12}, freq[] = {34, 50}
There can be following two possible BSTs
10 12
\ /
12 10
I II
Frequency of searches of 10 and 12 are 34 and 50 respectively.
The cost of tree I is 34*1 + 50*2 = 134
The cost of tree II is 50*1 + 34*2 = 118
Input: keys[] = {10, 12, 20}, freq[] = {34, 8, 50}
There can be following possible BSTs
10 12 20 10 20
\ / \ / \ /
12 10 20 12 20 10
\ / / \
20 10 12 12
I II III IV V
Among all possible BSTs, cost of the fifth BST is minimum.
Cost of the fifth BST is 1*50 + 2*34 + 3*8 = 142
1)最佳子结构:
可以使用以下公式递归计算freq [i..j]的最佳成本。
我们需要计算optCost(0,n-1)才能找到结果。
上面公式的想法很简单,我们一个接一个地尝试所有节点作为根(第二项中r从i到j变化)。当我们将第r个节点设为根时,我们递归地计算从i到r-1和r + 1到j的最优成本。
我们将i到j的频率总和相加(请参阅上式中的第一项),这是因为每次搜索都将通过根,并且每次搜索都将进行一次比较。
2)重叠子问题
以下是简单地遵循上述递归结构的递归实现。
C++
// A naive recursive implementation of
// optimal binary search tree problem
#include
using namespace std;
// A utility function to get sum of
// array elements freq[i] to freq[j]
int sum(int freq[], int i, int j);
// A recursive function to calculate
// cost of optimal binary search tree
int optCost(int freq[], int i, int j)
{
// Base cases
if (j < i) // no elements in this subarray
return 0;
if (j == i) // one element in this subarray
return freq[i];
// Get sum of freq[i], freq[i+1], ... freq[j]
int fsum = sum(freq, i, j);
// Initialize minimum value
int min = INT_MAX;
// One by one consider all elements
// as root and recursively find cost
// of the BST, compare the cost with
// min and update min if needed
for (int r = i; r <= j; ++r)
{
int cost = optCost(freq, i, r - 1) +
optCost(freq, r + 1, j);
if (cost < min)
min = cost;
}
// Return minimum value
return min + fsum;
}
// The main function that calculates
// minimum cost of a Binary Search Tree.
// It mainly uses optCost() to find
// the optimal cost.
int optimalSearchTree(int keys[],
int freq[], int n)
{
// Here array keys[] is assumed to be
// sorted in increasing order. If keys[]
// is not sorted, then add code to sort
// keys, and rearrange freq[] accordingly.
return optCost(freq, 0, n - 1);
}
// A utility function to get sum of
// array elements freq[i] to freq[j]
int sum(int freq[], int i, int j)
{
int s = 0;
for (int k = i; k <= j; k++)
s += freq[k];
return s;
}
// Driver Code
int main()
{
int keys[] = {10, 12, 20};
int freq[] = {34, 8, 50};
int n = sizeof(keys) / sizeof(keys[0]);
cout << "Cost of Optimal BST is "
<< optimalSearchTree(keys, freq, n);
return 0;
}
// This is code is contributed
// by rathbhupendra
C
// A naive recursive implementation of optimal binary
// search tree problem
#include
#include
// A utility function to get sum of array elements
// freq[i] to freq[j]
int sum(int freq[], int i, int j);
// A recursive function to calculate cost of optimal
// binary search tree
int optCost(int freq[], int i, int j)
{
// Base cases
if (j < i) // no elements in this subarray
return 0;
if (j == i) // one element in this subarray
return freq[i];
// Get sum of freq[i], freq[i+1], ... freq[j]
int fsum = sum(freq, i, j);
// Initialize minimum value
int min = INT_MAX;
// One by one consider all elements as root and
// recursively find cost of the BST, compare the
// cost with min and update min if needed
for (int r = i; r <= j; ++r)
{
int cost = optCost(freq, i, r-1) +
optCost(freq, r+1, j);
if (cost < min)
min = cost;
}
// Return minimum value
return min + fsum;
}
// The main function that calculates minimum cost of
// a Binary Search Tree. It mainly uses optCost() to
// find the optimal cost.
int optimalSearchTree(int keys[], int freq[], int n)
{
// Here array keys[] is assumed to be sorted in
// increasing order. If keys[] is not sorted, then
// add code to sort keys, and rearrange freq[]
// accordingly.
return optCost(freq, 0, n-1);
}
// A utility function to get sum of array elements
// freq[i] to freq[j]
int sum(int freq[], int i, int j)
{
int s = 0;
for (int k = i; k <=j; k++)
s += freq[k];
return s;
}
// Driver program to test above functions
int main()
{
int keys[] = {10, 12, 20};
int freq[] = {34, 8, 50};
int n = sizeof(keys)/sizeof(keys[0]);
printf("Cost of Optimal BST is %d ",
optimalSearchTree(keys, freq, n));
return 0;
}
Java
// A naive recursive implementation of optimal binary
// search tree problem
public class GFG
{
// A recursive function to calculate cost of
// optimal binary search tree
static int optCost(int freq[], int i, int j)
{
// Base cases
if (j < i) // no elements in this subarray
return 0;
if (j == i) // one element in this subarray
return freq[i];
// Get sum of freq[i], freq[i+1], ... freq[j]
int fsum = sum(freq, i, j);
// Initialize minimum value
int min = Integer.MAX_VALUE;
// One by one consider all elements as root and
// recursively find cost of the BST, compare the
// cost with min and update min if needed
for (int r = i; r <= j; ++r)
{
int cost = optCost(freq, i, r-1) +
optCost(freq, r+1, j);
if (cost < min)
min = cost;
}
// Return minimum value
return min + fsum;
}
// The main function that calculates minimum cost of
// a Binary Search Tree. It mainly uses optCost() to
// find the optimal cost.
static int optimalSearchTree(int keys[], int freq[], int n)
{
// Here array keys[] is assumed to be sorted in
// increasing order. If keys[] is not sorted, then
// add code to sort keys, and rearrange freq[]
// accordingly.
return optCost(freq, 0, n-1);
}
// A utility function to get sum of array elements
// freq[i] to freq[j]
static int sum(int freq[], int i, int j)
{
int s = 0;
for (int k = i; k <=j; k++)
s += freq[k];
return s;
}
// Driver code
public static void main(String[] args) {
int keys[] = {10, 12, 20};
int freq[] = {34, 8, 50};
int n = keys.length;
System.out.println("Cost of Optimal BST is " +
optimalSearchTree(keys, freq, n));
}
}
// This code is contributed by Sumit Ghosh
Python3
# A naive recursive implementation of
# optimal binary search tree problem
# A recursive function to calculate
# cost of optimal binary search tree
def optCost(freq, i, j):
# Base cases
if j < i: # no elements in this subarray
return 0
if j == i: # one element in this subarray
return freq[i]
# Get sum of freq[i], freq[i+1], ... freq[j]
fsum = Sum(freq, i, j)
# Initialize minimum value
Min = 999999999999
# One by one consider all elements as
# root and recursively find cost of
# the BST, compare the cost with min
# and update min if needed
for r in range(i, j + 1):
cost = (optCost(freq, i, r - 1) +
optCost(freq, r + 1, j))
if cost < Min:
Min = cost
# Return minimum value
return Min + fsum
# The main function that calculates minimum
# cost of a Binary Search Tree. It mainly
# uses optCost() to find the optimal cost.
def optimalSearchTree(keys, freq, n):
# Here array keys[] is assumed to be
# sorted in increasing order. If keys[]
# is not sorted, then add code to sort
# keys, and rearrange freq[] accordingly.
return optCost(freq, 0, n - 1)
# A utility function to get sum of
# array elements freq[i] to freq[j]
def Sum(freq, i, j):
s = 0
for k in range(i, j + 1):
s += freq[k]
return s
# Driver Code
if __name__ == '__main__':
keys = [10, 12, 20]
freq = [34, 8, 50]
n = len(keys)
print("Cost of Optimal BST is",
optimalSearchTree(keys, freq, n))
# This code is contributed by PranchalK
C#
// A naive recursive implementation of optimal binary
// search tree problem
using System;
class GFG
{
// A recursive function to calculate cost of
// optimal binary search tree
static int optCost(int []freq, int i, int j)
{
// Base cases
// no elements in this subarray
if (j < i)
return 0;
// one element in this subarray
if (j == i)
return freq[i];
// Get sum of freq[i], freq[i+1], ... freq[j]
int fsum = sum(freq, i, j);
// Initialize minimum value
int min = int.MaxValue;
// One by one consider all elements as root and
// recursively find cost of the BST, compare the
// cost with min and update min if needed
for (int r = i; r <= j; ++r)
{
int cost = optCost(freq, i, r-1) +
optCost(freq, r+1, j);
if (cost < min)
min = cost;
}
// Return minimum value
return min + fsum;
}
// The main function that calculates minimum cost of
// a Binary Search Tree. It mainly uses optCost() to
// find the optimal cost.
static int optimalSearchTree(int []keys, int []freq, int n)
{
// Here array keys[] is assumed to be sorted in
// increasing order. If keys[] is not sorted, then
// add code to sort keys, and rearrange freq[]
// accordingly.
return optCost(freq, 0, n-1);
}
// A utility function to get sum of array elements
// freq[i] to freq[j]
static int sum(int []freq, int i, int j)
{
int s = 0;
for (int k = i; k <=j; k++)
s += freq[k];
return s;
}
// Driver code
public static void Main()
{
int []keys = {10, 12, 20};
int []freq = {34, 8, 50};
int n = keys.Length;
Console.Write("Cost of Optimal BST is " +
optimalSearchTree(keys, freq, n));
}
}
// This code is contributed by Sam007
C++
// Dynamic Programming code for Optimal Binary Search
// Tree Problem
#include
using namespace std;
// A utility function to get sum of array elements
// freq[i] to freq[j]
int sum(int freq[], int i, int j);
/* A Dynamic Programming based function that calculates
minimum cost of a Binary Search Tree. */
int optimalSearchTree(int keys[], int freq[], int n)
{
/* Create an auxiliary 2D matrix to store results
of subproblems */
int cost[n][n];
/* cost[i][j] = Optimal cost of binary search tree
that can be formed from keys[i] to keys[j].
cost[0][n-1] will store the resultant cost */
// For a single key, cost is equal to frequency of the key
for (int i = 0; i < n; i++)
cost[i][i] = freq[i];
// Now we need to consider chains of length 2, 3, ... .
// L is chain length.
for (int L = 2; L <= n; L++)
{
// i is row number in cost[][]
for (int i = 0; i <= n-L+1; i++)
{
// Get column number j from row number i and
// chain length L
int j = i+L-1;
cost[i][j] = INT_MAX;
// Try making all keys in interval keys[i..j] as root
for (int r = i; r <= j; r++)
{
// c = cost when keys[r] becomes root of this subtree
int c = ((r > i)? cost[i][r-1]:0) +
((r < j)? cost[r+1][j]:0) +
sum(freq, i, j);
if (c < cost[i][j])
cost[i][j] = c;
}
}
}
return cost[0][n-1];
}
// A utility function to get sum of array elements
// freq[i] to freq[j]
int sum(int freq[], int i, int j)
{
int s = 0;
for (int k = i; k <= j; k++)
s += freq[k];
return s;
}
// Driver code
int main()
{
int keys[] = {10, 12, 20};
int freq[] = {34, 8, 50};
int n = sizeof(keys)/sizeof(keys[0]);
cout << "Cost of Optimal BST is " << optimalSearchTree(keys, freq, n);
return 0;
}
// This code is contributed by rathbhupendra
C
// Dynamic Programming code for Optimal Binary Search
// Tree Problem
#include
#include
// A utility function to get sum of array elements
// freq[i] to freq[j]
int sum(int freq[], int i, int j);
/* A Dynamic Programming based function that calculates
minimum cost of a Binary Search Tree. */
int optimalSearchTree(int keys[], int freq[], int n)
{
/* Create an auxiliary 2D matrix to store results
of subproblems */
int cost[n][n];
/* cost[i][j] = Optimal cost of binary search tree
that can be formed from keys[i] to keys[j].
cost[0][n-1] will store the resultant cost */
// For a single key, cost is equal to frequency of the key
for (int i = 0; i < n; i++)
cost[i][i] = freq[i];
// Now we need to consider chains of length 2, 3, ... .
// L is chain length.
for (int L=2; L<=n; L++)
{
// i is row number in cost[][]
for (int i=0; i<=n-L+1; i++)
{
// Get column number j from row number i and
// chain length L
int j = i+L-1;
cost[i][j] = INT_MAX;
// Try making all keys in interval keys[i..j] as root
for (int r=i; r<=j; r++)
{
// c = cost when keys[r] becomes root of this subtree
int c = ((r > i)? cost[i][r-1]:0) +
((r < j)? cost[r+1][j]:0) +
sum(freq, i, j);
if (c < cost[i][j])
cost[i][j] = c;
}
}
}
return cost[0][n-1];
}
// A utility function to get sum of array elements
// freq[i] to freq[j]
int sum(int freq[], int i, int j)
{
int s = 0;
for (int k = i; k <=j; k++)
s += freq[k];
return s;
}
// Driver program to test above functions
int main()
{
int keys[] = {10, 12, 20};
int freq[] = {34, 8, 50};
int n = sizeof(keys)/sizeof(keys[0]);
printf("Cost of Optimal BST is %d ",
optimalSearchTree(keys, freq, n));
return 0;
}
Java
// Dynamic Programming Java code for Optimal Binary Search
// Tree Problem
public class Optimal_BST2 {
/* A Dynamic Programming based function that calculates
minimum cost of a Binary Search Tree. */
static int optimalSearchTree(int keys[], int freq[], int n) {
/* Create an auxiliary 2D matrix to store results of
subproblems */
int cost[][] = new int[n + 1][n + 1];
/* cost[i][j] = Optimal cost of binary search tree that
can be formed from keys[i] to keys[j]. cost[0][n-1]
will store the resultant cost */
// For a single key, cost is equal to frequency of the key
for (int i = 0; i < n; i++)
cost[i][i] = freq[i];
// Now we need to consider chains of length 2, 3, ... .
// L is chain length.
for (int L = 2; L <= n; L++) {
// i is row number in cost[][]
for (int i = 0; i <= n - L + 1; i++) {
// Get column number j from row number i and
// chain length L
int j = i + L - 1;
cost[i][j] = Integer.MAX_VALUE;
// Try making all keys in interval keys[i..j] as root
for (int r = i; r <= j; r++) {
// c = cost when keys[r] becomes root of this subtree
int c = ((r > i) ? cost[i][r - 1] : 0)
+ ((r < j) ? cost[r + 1][j] : 0) + sum(freq, i, j);
if (c < cost[i][j])
cost[i][j] = c;
}
}
}
return cost[0][n - 1];
}
// A utility function to get sum of array elements
// freq[i] to freq[j]
static int sum(int freq[], int i, int j) {
int s = 0;
for (int k = i; k <= j; k++) {
if (k >= freq.length)
continue;
s += freq[k];
}
return s;
}
public static void main(String[] args) {
int keys[] = { 10, 12, 20 };
int freq[] = { 34, 8, 50 };
int n = keys.length;
System.out.println("Cost of Optimal BST is "
+ optimalSearchTree(keys, freq, n));
}
}
//This code is contributed by Sumit Ghosh
Python3
# Dynamic Programming code for Optimal Binary Search
# Tree Problem
INT_MAX = 2147483647
""" A Dynamic Programming based function that
calculates minimum cost of a Binary Search Tree. """
def optimalSearchTree(keys, freq, n):
""" Create an auxiliary 2D matrix to store
results of subproblems """
cost = [[0 for x in range(n)]
for y in range(n)]
""" cost[i][j] = Optimal cost of binary search
tree that can be formed from keys[i] to keys[j].
cost[0][n-1] will store the resultant cost """
# For a single key, cost is equal to
# frequency of the key
for i in range(n):
cost[i][i] = freq[i]
# Now we need to consider chains of
# length 2, 3, ... . L is chain length.
for L in range(2, n + 1):
# i is row number in cost
for i in range(n - L + 2):
# Get column number j from row number
# i and chain length L
j = i + L - 1
if i >= n or j >= n:
break
cost[i][j] = INT_MAX
# Try making all keys in interval
# keys[i..j] as root
for r in range(i, j + 1):
# c = cost when keys[r] becomes root
# of this subtree
c = 0
if (r > i):
c += cost[i][r - 1]
if (r < j):
c += cost[r + 1][j]
c += sum(freq, i, j)
if (c < cost[i][j]):
cost[i][j] = c
return cost[0][n - 1]
# A utility function to get sum of
# array elements freq[i] to freq[j]
def sum(freq, i, j):
s = 0
for k in range(i, j + 1):
s += freq[k]
return s
# Driver Code
if __name__ == '__main__':
keys = [10, 12, 20]
freq = [34, 8, 50]
n = len(keys)
print("Cost of Optimal BST is",
optimalSearchTree(keys, freq, n))
# This code is contributed by SHUBHAMSINGH10
C#
// Dynamic Programming C# code for Optimal Binary Search
// Tree Problem
using System;
class GFG
{
/* A Dynamic Programming based function that calculates
minimum cost of a Binary Search Tree. */
static int optimalSearchTree(int []keys, int []freq, int n) {
/* Create an auxiliary 2D matrix to store results of
subproblems */
int [,]cost = new int[n + 1,n + 1];
/* cost[i][j] = Optimal cost of binary search tree that
can be formed from keys[i] to keys[j]. cost[0][n-1]
will store the resultant cost */
// For a single key, cost is equal to frequency of the key
for (int i = 0; i < n; i++)
cost[i,i] = freq[i];
// Now we need to consider chains of length 2, 3, ... .
// L is chain length.
for (int L = 2; L <= n; L++) {
// i is row number in cost[][]
for (int i = 0; i <= n - L + 1; i++) {
// Get column number j from row number i and
// chain length L
int j = i + L - 1;
cost[i,j] = int.MaxValue;
// Try making all keys in interval keys[i..j] as root
for (int r = i; r <= j; r++) {
// c = cost when keys[r] becomes root of this subtree
int c = ((r > i) ? cost[i,r - 1] : 0)
+ ((r < j) ? cost[r + 1,j] : 0) + sum(freq, i, j);
if (c < cost[i,j])
cost[i,j] = c;
}
}
}
return cost[0,n - 1];
}
// A utility function to get sum of array elements
// freq[i] to freq[j]
static int sum(int []freq, int i, int j) {
int s = 0;
for (int k = i; k <= j; k++) {
if (k >= freq.Length)
continue;
s += freq[k];
}
return s;
}
public static void Main() {
int []keys = { 10, 12, 20 };
int []freq = { 34, 8, 50 };
int n = keys.Length;
Console.Write("Cost of Optimal BST is "
+ optimalSearchTree(keys, freq, n));
}
}
// This code is contributed by Sam007
输出:
Cost of Optimal BST is 142
上述幼稚递归方法的时间复杂度是指数的。应该注意的是,上述函数一次又一次地计算相同的子问题。我们可以看到在下面的递归树中,对于freq [1..4]重复了许多子问题。
由于再次调用了相同的问题,因此此问题具有“重叠子问题”属性。因此,最佳BST问题具有动态编程问题的两个属性(请参阅此内容)。像其他典型的动态规划(DP)问题一样,可以通过自下而上构造临时数组cost [] []来避免相同子问题的重新计算。
动态编程解决方案
以下是使用动态编程实现最佳BST问题的C / C++实现。我们使用辅助数组cost [n] [n]存储子问题的解。 cost [0] [n-1]将保留最终结果。实现中的挑战是,必须首先填充所有对角线值,然后填充对角线正上方的线上的值。换句话说,我们必须首先填充所有cost [i] [i]值,然后填充所有cost [i] [i + 1]值,然后填充所有cost [i] [i + 2]值。因此,如何以这种方式填充2D数组>实现中使用的思想与矩阵链乘法问题相同,我们对链长使用变量’L’,并逐个递增’L’。我们使用“ i”和“ L”的值计算列号“ j”。
C++
// Dynamic Programming code for Optimal Binary Search
// Tree Problem
#include
using namespace std;
// A utility function to get sum of array elements
// freq[i] to freq[j]
int sum(int freq[], int i, int j);
/* A Dynamic Programming based function that calculates
minimum cost of a Binary Search Tree. */
int optimalSearchTree(int keys[], int freq[], int n)
{
/* Create an auxiliary 2D matrix to store results
of subproblems */
int cost[n][n];
/* cost[i][j] = Optimal cost of binary search tree
that can be formed from keys[i] to keys[j].
cost[0][n-1] will store the resultant cost */
// For a single key, cost is equal to frequency of the key
for (int i = 0; i < n; i++)
cost[i][i] = freq[i];
// Now we need to consider chains of length 2, 3, ... .
// L is chain length.
for (int L = 2; L <= n; L++)
{
// i is row number in cost[][]
for (int i = 0; i <= n-L+1; i++)
{
// Get column number j from row number i and
// chain length L
int j = i+L-1;
cost[i][j] = INT_MAX;
// Try making all keys in interval keys[i..j] as root
for (int r = i; r <= j; r++)
{
// c = cost when keys[r] becomes root of this subtree
int c = ((r > i)? cost[i][r-1]:0) +
((r < j)? cost[r+1][j]:0) +
sum(freq, i, j);
if (c < cost[i][j])
cost[i][j] = c;
}
}
}
return cost[0][n-1];
}
// A utility function to get sum of array elements
// freq[i] to freq[j]
int sum(int freq[], int i, int j)
{
int s = 0;
for (int k = i; k <= j; k++)
s += freq[k];
return s;
}
// Driver code
int main()
{
int keys[] = {10, 12, 20};
int freq[] = {34, 8, 50};
int n = sizeof(keys)/sizeof(keys[0]);
cout << "Cost of Optimal BST is " << optimalSearchTree(keys, freq, n);
return 0;
}
// This code is contributed by rathbhupendra
C
// Dynamic Programming code for Optimal Binary Search
// Tree Problem
#include
#include
// A utility function to get sum of array elements
// freq[i] to freq[j]
int sum(int freq[], int i, int j);
/* A Dynamic Programming based function that calculates
minimum cost of a Binary Search Tree. */
int optimalSearchTree(int keys[], int freq[], int n)
{
/* Create an auxiliary 2D matrix to store results
of subproblems */
int cost[n][n];
/* cost[i][j] = Optimal cost of binary search tree
that can be formed from keys[i] to keys[j].
cost[0][n-1] will store the resultant cost */
// For a single key, cost is equal to frequency of the key
for (int i = 0; i < n; i++)
cost[i][i] = freq[i];
// Now we need to consider chains of length 2, 3, ... .
// L is chain length.
for (int L=2; L<=n; L++)
{
// i is row number in cost[][]
for (int i=0; i<=n-L+1; i++)
{
// Get column number j from row number i and
// chain length L
int j = i+L-1;
cost[i][j] = INT_MAX;
// Try making all keys in interval keys[i..j] as root
for (int r=i; r<=j; r++)
{
// c = cost when keys[r] becomes root of this subtree
int c = ((r > i)? cost[i][r-1]:0) +
((r < j)? cost[r+1][j]:0) +
sum(freq, i, j);
if (c < cost[i][j])
cost[i][j] = c;
}
}
}
return cost[0][n-1];
}
// A utility function to get sum of array elements
// freq[i] to freq[j]
int sum(int freq[], int i, int j)
{
int s = 0;
for (int k = i; k <=j; k++)
s += freq[k];
return s;
}
// Driver program to test above functions
int main()
{
int keys[] = {10, 12, 20};
int freq[] = {34, 8, 50};
int n = sizeof(keys)/sizeof(keys[0]);
printf("Cost of Optimal BST is %d ",
optimalSearchTree(keys, freq, n));
return 0;
}
Java
// Dynamic Programming Java code for Optimal Binary Search
// Tree Problem
public class Optimal_BST2 {
/* A Dynamic Programming based function that calculates
minimum cost of a Binary Search Tree. */
static int optimalSearchTree(int keys[], int freq[], int n) {
/* Create an auxiliary 2D matrix to store results of
subproblems */
int cost[][] = new int[n + 1][n + 1];
/* cost[i][j] = Optimal cost of binary search tree that
can be formed from keys[i] to keys[j]. cost[0][n-1]
will store the resultant cost */
// For a single key, cost is equal to frequency of the key
for (int i = 0; i < n; i++)
cost[i][i] = freq[i];
// Now we need to consider chains of length 2, 3, ... .
// L is chain length.
for (int L = 2; L <= n; L++) {
// i is row number in cost[][]
for (int i = 0; i <= n - L + 1; i++) {
// Get column number j from row number i and
// chain length L
int j = i + L - 1;
cost[i][j] = Integer.MAX_VALUE;
// Try making all keys in interval keys[i..j] as root
for (int r = i; r <= j; r++) {
// c = cost when keys[r] becomes root of this subtree
int c = ((r > i) ? cost[i][r - 1] : 0)
+ ((r < j) ? cost[r + 1][j] : 0) + sum(freq, i, j);
if (c < cost[i][j])
cost[i][j] = c;
}
}
}
return cost[0][n - 1];
}
// A utility function to get sum of array elements
// freq[i] to freq[j]
static int sum(int freq[], int i, int j) {
int s = 0;
for (int k = i; k <= j; k++) {
if (k >= freq.length)
continue;
s += freq[k];
}
return s;
}
public static void main(String[] args) {
int keys[] = { 10, 12, 20 };
int freq[] = { 34, 8, 50 };
int n = keys.length;
System.out.println("Cost of Optimal BST is "
+ optimalSearchTree(keys, freq, n));
}
}
//This code is contributed by Sumit Ghosh
Python3
# Dynamic Programming code for Optimal Binary Search
# Tree Problem
INT_MAX = 2147483647
""" A Dynamic Programming based function that
calculates minimum cost of a Binary Search Tree. """
def optimalSearchTree(keys, freq, n):
""" Create an auxiliary 2D matrix to store
results of subproblems """
cost = [[0 for x in range(n)]
for y in range(n)]
""" cost[i][j] = Optimal cost of binary search
tree that can be formed from keys[i] to keys[j].
cost[0][n-1] will store the resultant cost """
# For a single key, cost is equal to
# frequency of the key
for i in range(n):
cost[i][i] = freq[i]
# Now we need to consider chains of
# length 2, 3, ... . L is chain length.
for L in range(2, n + 1):
# i is row number in cost
for i in range(n - L + 2):
# Get column number j from row number
# i and chain length L
j = i + L - 1
if i >= n or j >= n:
break
cost[i][j] = INT_MAX
# Try making all keys in interval
# keys[i..j] as root
for r in range(i, j + 1):
# c = cost when keys[r] becomes root
# of this subtree
c = 0
if (r > i):
c += cost[i][r - 1]
if (r < j):
c += cost[r + 1][j]
c += sum(freq, i, j)
if (c < cost[i][j]):
cost[i][j] = c
return cost[0][n - 1]
# A utility function to get sum of
# array elements freq[i] to freq[j]
def sum(freq, i, j):
s = 0
for k in range(i, j + 1):
s += freq[k]
return s
# Driver Code
if __name__ == '__main__':
keys = [10, 12, 20]
freq = [34, 8, 50]
n = len(keys)
print("Cost of Optimal BST is",
optimalSearchTree(keys, freq, n))
# This code is contributed by SHUBHAMSINGH10
C#
// Dynamic Programming C# code for Optimal Binary Search
// Tree Problem
using System;
class GFG
{
/* A Dynamic Programming based function that calculates
minimum cost of a Binary Search Tree. */
static int optimalSearchTree(int []keys, int []freq, int n) {
/* Create an auxiliary 2D matrix to store results of
subproblems */
int [,]cost = new int[n + 1,n + 1];
/* cost[i][j] = Optimal cost of binary search tree that
can be formed from keys[i] to keys[j]. cost[0][n-1]
will store the resultant cost */
// For a single key, cost is equal to frequency of the key
for (int i = 0; i < n; i++)
cost[i,i] = freq[i];
// Now we need to consider chains of length 2, 3, ... .
// L is chain length.
for (int L = 2; L <= n; L++) {
// i is row number in cost[][]
for (int i = 0; i <= n - L + 1; i++) {
// Get column number j from row number i and
// chain length L
int j = i + L - 1;
cost[i,j] = int.MaxValue;
// Try making all keys in interval keys[i..j] as root
for (int r = i; r <= j; r++) {
// c = cost when keys[r] becomes root of this subtree
int c = ((r > i) ? cost[i,r - 1] : 0)
+ ((r < j) ? cost[r + 1,j] : 0) + sum(freq, i, j);
if (c < cost[i,j])
cost[i,j] = c;
}
}
}
return cost[0,n - 1];
}
// A utility function to get sum of array elements
// freq[i] to freq[j]
static int sum(int []freq, int i, int j) {
int s = 0;
for (int k = i; k <= j; k++) {
if (k >= freq.Length)
continue;
s += freq[k];
}
return s;
}
public static void Main() {
int []keys = { 10, 12, 20 };
int []freq = { 34, 8, 50 };
int n = keys.Length;
Console.Write("Cost of Optimal BST is "
+ optimalSearchTree(keys, freq, n));
}
}
// This code is contributed by Sam007
输出:
Cost of Optimal BST is 142
笔记
1)上述解决方案的时间复杂度为O(n ^ 4)。通过预先计算频率之和而不是一次又一次地调用sum(),可以很容易地将时间复杂度降低到O(n ^ 3)。
2)在上述解决方案中,我们仅计算了最佳成本。可以轻松修改解决方案以存储BST的结构。我们可以创建另一个大小为n的辅助数组来存储树的结构。我们要做的就是将所选的“ r”存储在最里面的循环中。