题目:
给n个节点以及每个节点的将要被查询的概率pi,然后把它补充成一个满二叉树,用来补充的节点有n+1个,即di ,每个 di 也有一个查询的概率 qi 。构造最优的二叉搜索树,使总的查询次数最少。
最优二叉搜索树:我的理解是,必须保持原二叉树的中序遍历序列不变的前提下,通过将大概率节点尽量排到接近根的位置,使得总查询次数最少的树。它根哈夫曼编码有相似之处,就是贪心的使大概率节点接近树根,但是它不能够改变原树的中序遍历稳定结构。
思路:
因为最优二字,使用的是dp的思想,把整棵树分成若干子树,其子树也是最优二叉搜索树,满足最优子结构。由这些子树组成得到的一棵树即最终的最优二叉搜索树。详见代码。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1000+10;
const double INF=1e9+7;
int n;
double p[MAXN];//每一个节点的查找概率
double q[MAXN];//伪关键字的搜索概率
double dp[MAXN][MAXN];//dp[i][j] 从节点i到节点j构成的最优查找树的PH值的最小值
int root[MAXN][MAXN];//root[i][j] 从节点i到节点j构成的最优查找树的根节点
double sum[MAXN][MAXN];//sum[i][j] 区间i到j的的区间概率和
void solve()
{
for(int len=1; len<=n; len++)
{
for(int i=1; i<&