使用c语言解决下列的问题:给定标识符集(a 1 , a 2 , …a n ),这些字符的下标从1开始按自然序编号,p i 是对a i 成功检索的概率, q i 是不成功检索的概率, 且∑ (1<=i<=n) p i +∑ (0<=i<=n) q i =1,问:它的最优二分检索树是怎样的? 输入格式: 第1行是n,表示字符个数; 第2行是这n个字符的成功检索概率p i , 0<p i <1; 第3行是失败检索概率q i ,0<q i <1,且∑ (1<=i<=n) p i +∑ (0<=i<=n) q i =1。 输出格式: 最优二分检索树先根遍历时得到的字符编号序列。 输入样例1: 4 0.1875 0.1875 0.0625 0.0625 0.125 0.1875 0.0625 0.0625 0.0625 输出样例1: 2 1 3 4 输入样例2: 5 0.1524 0.1369 0.0179 0.0007 0.3081 0.1567 0.1022 0.0682 0.0476 0.0084 0.0009 输出样例2: 2 1 5 3 4 给定标识符集(a 1 , a 2 , …a n ),这些字符的下标从1开始按自然序编号,p i 是对a i 成功检索的概率, q i 是不成功检索的概率, 且∑ (1<=i<=n) p i +∑ (0<=i<=n) q i =1,问:它的最优二分检索树是怎样的? 输入格式: 第1行是n,表示字符个数; 第2行是这n个字符的成功检索概率p i , 0<p i <1; 第3行是失败检索概率q i ,0<q i <1,且∑ (1<=i<=n) p i +∑ (0<=i<=n) q i =1。 输出格式: 最优二分检索树先根遍历时得到的字符编号序列。 输入样例1: 4 0.1875 0.1875 0.0625 0.0625 0.125 0.1875 0.0625 0.0625 0.0625 输出样例1: 2 1 3 4 输入样例2: 5 0.1524 0.1369 0.0179 0.0007 0.3081 0.1567 0.1022 0.0682 0.0476 0.0084 0.0009 输出样例2: 2 1 5 3 4
时间: 2024-03-26 15:38:12 浏览: 46
最优二分搜索树 用C语言实现
5星 · 资源好评率100%
```c
#include <stdio.h>
#include <stdlib.h>
#define MAXN 1005
#define INF 0x3f3f3f3f
double p[MAXN], q[MAXN];
double f[MAXN][MAXN];
int root[MAXN][MAXN];
void optSearchTree(int n) {
// 初始化
for (int i = 1; i <= n + 1; i++) {
f[i][i - 1] = q[i - 1];
root[i][i - 1] = i - 1;
}
// 枚举区间长度
for (int len = 1; len <= n; len++) {
// 枚举区间起点
for (int i = 1; i + len - 1 <= n; i++) {
int j = i + len - 1;
f[i][j] = INF;
// 枚举分割点
for (int k = i; k <= j; k++) {
double sum = 0;
for (int l = i; l <= j; l++) {
sum += p[l];
}
if (f[i][k - 1] + f[k + 1][j] + sum < f[i][j]) {
f[i][j] = f[i][k - 1] + f[k + 1][j] + sum;
root[i][j] = k;
}
}
}
}
}
void preorderTraversal(int l, int r) {
if (l > r) {
return;
}
int k = root[l][r];
printf("%d ", k);
preorderTraversal(l, k - 1);
preorderTraversal(k + 1, r);
}
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%lf", &p[i]);
}
for (int i = 0; i <= n; i++) {
scanf("%lf", &q[i]);
}
optSearchTree(n);
preorderTraversal(1, n);
return 0;
}
```
阅读全文