算法导论 · 动态规划 · 最优二分检索树

  • 算法说明
    构造最佳二叉搜索树:
    如果已知集合元素的搜索概率,那么自然会提出一个关于最优二叉搜索树的问题,搜索中的平均比较数是可能的最小值。
    例如,考虑四个要搜索的键a、b、c和d,其概率分别为0.1、0.2、0.4和0.3。则0.11+0.22+0.43+0.34=2.9
  • 源代码
#include <cstdio>
#include <cstring>

#define maxn 101
#define minc(a, b) (a) > (b) ? (b) : (a)
#define INF 1 << 29 

double c[maxn][maxn], p[maxn];
int n, root[maxn][maxn];
int main() {
	memset(c, 0, sizeof(c));
	memset(root, 0, sizeof(root));
	freopen("7.optimalBinarySearchTrees.txt", "r", stdin);
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) {
		scanf("%lf", &p[i]);
	}
	
	//init
	for(int i = 0; i <= n; i++) {
		c[i][i-1] = 0;
		c[i][i] = p[i];
		root[i][i] = i;
	}
	for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n - k + 1; i++) {
            int j = i + k - 1;
			double sum = 0;
            c[i][j] = INF;

			for(int k = i; k <= j; k++) {
				sum += p[k];
			}
//			printf("%d, %d, %.1f\n", i, j, sum);
            for (int r = i; r <= j; r++) {
                double t = c[i][r - 1] + c[r + 1][j] + sum;
                if (c[i][j] > t) {
                    c[i][j] = t;
                    root[i][j] = r;
                }
            }
        }
    }
	
	for(int i = 1; i <= n + 1; i++) {
		for(int j = 0; j <= n; j++) {
			if(c[i][j] == 0) printf("null ");
			else printf("%-5.1f", c[i][j]);
		}
		printf("\n");
	}
	
	printf("\n");
	for(int i = 1; i <= n + 1; i++) {
		for(int j = 0; j <= n; j++) {
			if(c[i][j] == 0) printf("null ");
			else printf("  %-3d", root[i][j]);
		}
		printf("\n");
	}	
	
	return 0;
}
  • 输入数据
    在这里插入图片描述
  • 运行结果
    在这里插入图片描述
发布了77 篇原创文章 · 获赞 40 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/y_dd6011/article/details/97434384