标签:
这个内容是去年暑假讲的,但是一直没有实现,
其实说白了就是区间dp,求一个序列构成二叉树,中序遍历有序.
核心和其他区间dp一样,枚举中间值.然后枚举出来后再将整个区间的概率累加,因为相当于加深了一层.
JAVA代码,附测试数据
import java.util.Arrays; import java.util.Scanner; public class Main { /** * 输入p: 访问概率数组; 0,1,....n是排好序的Key值 * 输出A=new float[n][n]: 最优时间矩阵 * 输出R=new int[n][n]: 根结点矩阵 * @param p * @param A * @param R */ static void optimalBST(double[] p, double[][] A, int[][] R) { int n = p.length; Arrays.sort(p); for (int i = 0; i < n; i++) { A[i][i] = p[i]; R[i][i] = i; // the root is itself } for (int len = 1; len < n; len++) { for (int st = 0; st + len < n; st++) { int ed = st + len; int root = st; double min = Double.MAX_VALUE; for (int k = st; k <= ed; k++) { double tmp; if (k == st) tmp = A[k + 1][ed]; else if (k == ed) tmp = A[st][k - 1]; else tmp = A[k + 1][ed] + A[st][k - 1]; if (min > tmp) { min = tmp; root = k; } } R[st][ed] = root; A[st][ed] = min; for (int i = st; i <= ed; i++) A[st][ed] += p[i]; } } } public static void print(int st,int ed,int [][] R){ if(st==ed) { System.out.print(R[st][ed]); return; } System.out.print("("); print(st,R[st][ed]-1,R); System.out.print(")"); System.out.print(R[st][ed]); System.out.print("("); print(R[st][ed]+1,ed,R); System.out.print(")"); } public static void main(String[] args) { //Scanner input = new Scanner(System.in); double [][] A = new double[5][5]; int [][] R = new int[5][5]; // optimalBST1(new double [] {0.15, 0.10,0.05,0.10,0.20},A,R); // System.out.println(A[0][4]); // print(0,4,R); optimalBST(new double [] {0.15, 0.10,0.05,0.10,0.20},A,R); System.out.println(A[0][4]); print(0,4,R); } }
标签:
原文地址:http://blog.csdn.net/gg_gogoing/article/details/44975679