題目:給定一串有序數字f,生成一個BST,使得Σ deep(i)* f(i)最小。
分析:動態規劃,區間dp。按長度遞增枚舉區間。
狀態方程 f(s,e)= min(f(s,k-1)+ f(k+1,e)+ sum(s,e) - f(k))。
說明:很久沒有寫dp了╮(╯▽╰)╭。
#include <cstring>
#include <cstdio>
int frequency[255];
int interval[255][255];
int cost[255][255];
int main()
{
int n;
while (~scanf("%d",&n)) {
for (int i = 1; i <= n; ++ i) {
scanf("%d",&frequency[i]);
}
// 计算区间和,子树整体深度+1时,子树权值增加区间和
memset(interval, 0, sizeof(interval));
for (int i = 1; i <= n; ++ i) {
interval[i][i-1] = 0;
for (int j = i; j <= n; ++ j) {
interval[i][j] = interval[i][j-1] + frequency[j];
}
}
// 区间dp,枚举区间中的每个点作为根时的值,取最小值
memset(cost, 0, sizeof(cost));
for (int l = 2; l <= n; ++ l) {
for (int s = 1; s+l-1 <= n; ++ s) {
int e = s+l-1;
cost[s][e] = 10000000;
for (int k = s; k <= e; ++ k) {
int Ltree = cost[s][k-1] + interval[s][k-1];
int Rtree = cost[k+1][e] + interval[k+1][e];
if (cost[s][e] > Ltree + Rtree) {
cost[s][e] = Ltree + Rtree;
}
}
}
}
printf("%d\n",cost[1][n]);
}
return 0;
}