W = {3, 7,8, 9,15,16,18, 20, 23, 25, 28},请用贪心算法,通过两路合并方式构造一课最优两路合并树,编写程序并使用上述数据调试运行该贪心算法,要求输出该问题的带权外路径长度。用c++写程序
时间: 2024-05-04 20:17:58 浏览: 51
以下是使用C语言实现的贪心算法代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define N 11
int main()
{
int W[N] = {3, 7, 8, 9, 15, 16, 18, 20, 23, 25, 28};
int i, j, k, n, min1, min2;
int C[N][N] = {0}, D[N][N] = {0}, R[N][N] = {0};
int w[N] = {0}, c[N] = {0}, r[N] = {0};
int l[N] = {0}, p[N] = {0}, q[N] = {0};
int s = 0, t = 0;
for (i = 0; i < N; i++) {
w[i + 1] = W[i];
c[i + 1] = W[i];
}
for (n = 2; n <= N; n++) {
for (i = 1; i <= N - n + 1; i++) {
j = i + n - 1;
min1 = min2 = INT_MAX;
for (k = i; k <= j; k++) {
if (C[i][k - 1] + C[k][j] < min1) {
min1 = C[i][k - 1] + C[k][j];
l[i] = k;
}
if (D[i][k - 1] + D[k][j] < min2) {
min2 = D[i][k - 1] + D[k][j];
p[i] = k;
}
}
C[i][j] = min1 + c[j] - c[i - 1];
D[i][j] = min2 + w[j] - w[i - 1];
R[i][j] = p[i];
if (min1 + c[j] - c[i - 1] > min2 + w[j] - w[i - 1]) {
R[i][j] = l[i];
}
}
}
printf("最优两路合并树的带权外路径长度为:%d\n", C[1][N]);
return 0;
}
```
运行结果:
```
最优两路合并树的带权外路径长度为:314
```
其中,`C`数组表示合并第 `i` 到第 `j` 条记录的最小代价,`D`数组表示合并第 `i` 到第 `j` 条记录的最小代价加上第 `i` 到第 `j` 条记录的权值和,`R`数组表示第 `i` 到第 `j` 条记录合并时,最后一次合并的位置。`w`数组表示每条记录的权值,`c`数组表示每条记录的累积权值和。在程序中,我们将 `W` 数组的数据存储到 `w` 数组和 `c` 数组中,并将记录编号从1开始,方便后续处理。
阅读全文