最优排序二叉树问题
给n个符号建立一棵二叉树,虽然平衡树的高度最小,但如果各个符号的频
率相差很大,平衡反而不好。要求构造一颗最优二叉排序树,使得每个关键字和
频率和深度的乘积之和最小。
7
729 243 81 27 9 3 1
1636
提示:从大到小连成一条链,此时样例答案最小
dp[i][j]代表从i到j形成一颗子树的最小值
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
int dp[1100][1100],k[1100][1100],A[1100],sum[1100];
int section(int l,int r)
{
return sum[r]-sum[l-1];
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&A[i]);
sort(A+1,A+n+1);
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+A[i];
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
dp[i][j]=1e9;
}
}
for(int i=1; i<=n; i++)
dp[i][i]=A[i],k[i][i]=i;
for(int len=1;len<n;len++)
{
for(int i=1;i+len<=n;i++)
{
int j=i+len;
for(int t=k[i][j-1];t<=k[i+1][j];t++)
{
int tem=dp[i][t-1]+dp[t+1][j]+section(i,j);
if(tem<=dp[i][j])
{
k[i][j]=t;
dp[i][j]=tem;
}
}
}
}
printf("%d\n",dp[1][n]);
}