📜  最优二叉搜索树 | DP-24

📅  最后修改于: 2021-09-17 06:47:48             🧑  作者: Mango

给定搜索键的排序数组键[0.. n-1]和频率计数的数组freq[0.. n-1] ,其中freq[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\left ( i, \right j) = \sum_{k=i}^{j} freq \begin{bmatrix}k\end{bmatrix} + min_{r=i}^{j}\begin{bmatrix} optcost(i, r-1) + optcost(r+1, j) \end{bmatrix}
我们需要计算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


Javascript


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


Javascript


输出:

Cost of Optimal BST is 142

上述朴素递归方法的时间复杂度是指数级的。需要注意的是,上述函数一次又一次地计算相同的子问题。我们可以看到在以下 freq[1..4] 的递归树中重复了许多子问题。

由于再次调用相同的子问题,因此该问题具有重叠子问题的属性。因此,最优 BST 问题具有动态规划问题的两个属性(参见this 和 this)。与其他典型的动态规划 (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

蟒蛇3

# 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

Javascript


输出:

Cost of Optimal BST is 142

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程