zoukankan      html  css  js  c++  java
  • 最优二叉搜索树

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <list>
     4 #include <vector>
     5 
     6 using namespace std;
     7 
     8 double e[10][10];//e[i][j]表示在k[i-1]和k[j+1]之间的关键字(全开区间)作为一颗有根树的最小搜索代价
     9 double w[10][10];//w[i][j]表示在k[i-1]和k[j+1]之间的关键字(全开区间)的概率之和
    10 double optimal_bst(double *p, double *q, const int n) {//n为关键字数量,假装n小于9,(逃
    11     for (int i = 1;i <= n + 1;i++)
    12         w[i][i - 1] = q[i - 1], e[i][i - 1] = q[i - 1];
    13     //e[1][n]
    14     //状态转移方程:e[i][j]=e[i][r-1]+p[r]+e[r+1][j]+w[i][r-1]+w[r+1][j],其中两个w为区间内点下降获得的代价
    15     //方程可转化为:e[i][j]=e[i][r-1]+e[r+1][j]+w[i][j]
    16     for(int l=1;l<=n;l++)
    17         for (int beg = 1;beg <= n - l + 1;beg++) {
    18             int end = beg + l - 1;
    19             w[beg][end] = w[beg][end - 1] + p[end] + q[end];
    20             e[beg][end] = INT_MAX;
    21             for (int root = beg;root <= end;root++)
    22                 e[beg][end] = min(e[beg][end], e[beg][root - 1] + e[root + 1][end] + w[beg][end]);
    23         }
    24     cout << e[1][n] << endl;
    25     return e[1][n];
    26 }

    感觉这个比较妙的主要是状态的定义,e[i][j]表示在k[i-1]和k[j+1]之间的关键字(全开区间)作为一颗有根树的最小搜索代价,w[i][j]表示在k[i-1]和k[j+1]之间的关键字(全开区间)的概率之和,同时也把e[i][i-1]和w[i][i-1]的情况包括进去了,即伪节点的概率,除了注意一些边界问题,难度还行。以上,跑过书里的一个例子,答案2.75

    1 int main(void) {
    2     double p[10] = { 0.0,0.15,0.10,0.05,0.10,0.20 };
    3     double q[10] = { 0.05,0.10,0.05,0.05,0.05,0.10 };
    4     optimal_bst(p, q, 5);
    5 
    6     return 0;
    7 }
  • 相关阅读:
    安恒X计划12月月赛
    IDA 7.0在Mojava更新后打不开的问题
    ev3_basic——HITCON CTF 2018
    护网杯划水
    python开发中容易犯的错误整合
    使用gunicorn部署Flask项目
    记两个国外CTF的弱pwn
    MongoDB和pymongo自用手册
    深入理解python之二——python列表和元组
    深入理解python之一——python3对象的一些特性
  • 原文地址:https://www.cnblogs.com/schsb/p/8686324.html
Copyright © 2011-2022 走看看