import java.util.Scanner; public class OBSTree { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Get the number of keys System.out.print("Enter the number of keys: "); int n = scanner.nextInt(); // Input probabilities for keys (P array) double[] P = new double[n]; System.out.println("Enter probabilities for the keys:"); for (int i = 0; i < n; i++) { System.out.print("P[" + i + "]: "); P[i] = scanner.nextDouble(); } // Input probabilities for dummy nodes (Q array) double[] Q = new double[n + 1]; System.out.println("Enter probabilities for the dummy nodes:"); for (int i = 0; i <= n; i++) { System.out.print("Q[" + i + "]: "); Q[i] = scanner.nextDouble(); } // Call the OBST procedure OBSTResult result = OBST(P, Q, n); // Print the cost and root matrices System.out.println("\nCost Matrix C:"); for (int i = 0; i <= n; i++) { for (int j = 0; j <= n; j++) { System.out.printf("%.2f ", result.C[i][j]); } System.out.println(); } System.out.println("\nRoot Matrix R:"); for (int i = 0; i <= n; i++) { for (int j = 0; j <= n; j++) { System.out.printf("%d ", result.R[i][j]); } System.out.println(); } // Print the optimal cost System.out.printf("\nThe optimal cost is: %.2f\n", result.C[0][n]); } public static OBSTResult OBST(double[] P, double[] Q, int n) { double[][] C = new double[n + 1][n + 1]; double[][] W = new double[n + 1][n + 1]; int[][] R = new int[n + 1][n + 1]; // Initialize for single nodes and dummy nodes for (int i = 0; i <= n; i++) { W[i][i] = Q[i]; C[i][i] = 0; R[i][i] = 0; if (i < n) { W[i][i + 1] = Q[i] + Q[i + 1] + P[i]; C[i][i + 1] = W[i][i + 1]; R[i][i + 1] = i + 1; } } // Compute the OBST for all subarrays of length >= 2 for (int m = 2; m <= n; m++) { // Tree size for (int i = 0; i <= n - m; i++) { int j = i + m; W[i][j] = W[i][j - 1] + P[j - 1] + Q[j]; // Find optimal root in range that minimizes cost double minCost = Double.MAX_VALUE; int bestRoot = -1; // Apply Knuth's optimization to reduce the number of root checks for (int k = R[i][j - 1]; k <= R[i + 1][j]; k++) { double cost = C[i][k - 1] + C[k][j]; if (cost < minCost) { minCost = cost; bestRoot = k; } } C[i][j] = W[i][j] + minCost; R[i][j] = bestRoot; } } // Return the computed cost and root matrices return new OBSTResult(C, W, R); } } // Helper class to store the results of the OBST function class OBSTResult { double[][] C; double[][] W; int[][] R; OBSTResult(double[][] C, double[][] W, int[][] R) { this.C = C; this.W = W; this.R = R; } }