注意: 代码中省略了资源释放部分。
反省:长时间没有碰电脑,平时写写伪码,忽略了很多细节,电脑对此要求很严格,在2个月没碰c++,今天遇到最大的失误就是double写成了int精度错了导致代码一直调试不出来不得不说这是个巨大的失误。
#include<iostream>
using namespace std;
#define inf 10000
//p 1 2 3
//q 0 1 2 3
/*
定义c[i,j]:节点i到j最小子树值
假定选择k=i,i+1,……,j 为root节点
分成 i……k-1 k k+1……j 三块
边界情况k=i或者j 出现空树情况 c[i,i-1]=q[i-1]
其余情况c[i,j]= min c[i,k-1]+c[k+1,j]+sum(p,i,j)
*/
void optimal_tree(double p[], double q[], size_t n)
{
double **r = new double*[n + 1];
double **m = new double*[n + 1];
int i, j, k, l;
double s;
for (i = 0; i <= n; ++i)
{
r[i] = new double[n+1];
m[i] = new double[n+1];
}
for (i = 1; i <= n; ++i)
{
r[i][i - 1] = q[i - 1];
m[i][i - 1] = q[i - 1];
}
for (l = 1; l < n; ++l)
{
for (i = 1; i <= n - l; ++i)
{
j = i + l - 1;
r[i][j] = inf;
m[i][j] = m[i][j - 1] + p[j] + q[j];
for (k = i; k <= j; ++k)
{
s = r[i][k - 1] + r[k + 1][j] + m[i][j];
if (s < r[i][j])
{
r[i][j] = s;
}
}
}
}
cout << r[1][n-1] << endl;
}
int main()
{
double p[] = { 0,0.15,0.1,0.05,0.1,0.2 };
double q[] = { 0.05,0.10,0.05,0.05,0.05,0.10 };
optimal_tree(p, q, 6);
system("pause");
return 0;
}