uva10304-最优二叉搜索树

题意:给你每个树节点被查找的频率 F,那么某个节点的花费是 K * F,  K 是 根节点到当前节点的路径长度。树的总花费是 sum(Ki * Fi)。

问,树的最小花费是多少。

原题链接

解题思路:

区间DP,首先计算 只有一个根节点的花费,是0,然后计算每连续俩个节点的花费。 计算每连续三个节点的花费,最后是整个树的花费。

设 dp[i][j] 表示 从 下标 i 到下表 j 的花费 ,那么 dp[i][j] =  min(dp[i][k-1] + dp[k+1][j] + 以k为根节点的花费);

以k为根节点的花费 = sum[i....k-1] + sum[k+1.....j]。

这样思考,在以下标 K 为根节点得到时候,dp[i][k-1] 和 dp[k+1][j]  肯定都是最优的二叉搜索树花费。

如果以 K 为根,等价于把树的高度 +1,即路径变长,并且,此时应该减去 k 的花费。

对应代码 

int total = sum[e] - sum[s - 1];
int
val = dp[s][k - 1] + dp[k + 1][e] + total - num[k];
sum是前缀和,total内部包含了num[k],所以应该减去

 

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Main
{
    static final int N = 253;
    //static final int N = 5;
    static int dp[][] = new int[N][N];
    static int num[] = new int[N];
    static int sum[] = new int[N];
    static int INF = (int) 1e6;
    static int n;

    public static void main(String[] args) throws FileNotFoundException
    {
         Scanner scanner = new Scanner(System.in);
        //Scanner scanner = new Scanner(new File("/Users/caicai/in"));
        while (scanner.hasNextInt())
        {
            initdp();
            n = scanner.nextInt();
            for (int i = 1; i <= n; i++)
            {
                num[i] = scanner.nextInt();
                sum[i] = sum[i - 1] + num[i];
            }
            dp();
        }
    }

    static void initdp()
    {
        for (int i = 0; i < N; i++)
        {
            sum[i] = 0;
            for (int j = 0; j < N; j++)
            {
                dp[i][j] = 0;
            }
        }

    }

    static void dp()
    {
        for (int len = 1; len < n; len++)
        {
            for (int i = 1;; i++)
            {
                int s = i;
                int e = i + len;
                if (e > n) break;
                int total = sum[e] - sum[s - 1];
                int ans = INF;
                for (int k = s; k <= e; k++)
                {
                    int val = dp[s][k - 1] + dp[k + 1][e] + total - num[k];
                    if (ans > val) ans = val;
                }
                dp[s][e] = ans;
            }
        }
        System.out.println(dp[1][n]);
    }

}

 

 

 

 

 

 

题目:

 

Given a set S = (e1, e2, ..., en) of n distinct elements such that e1 < e2 < . . . < en and considering a binary search tree (see the previous problem) of the elements of S, it is desired that higher the query frequency of an element, closer will it be to the root. The cost of accessing an element ei of S in a tree (cost(ei)) is equal to the number of edges in the path that connects the root with the node that contains the element. Given the query frequencies of the elements of S, (f(e1), f(e2), . . . , f(en)), we say that the total cost of a tree is the following summation:

f(e1) ∗ cost(e1) + f(e2) ∗ cost(e2) + . . . + f(en) ∗ cost(en)

In this manner, the tree with the lowest total cost is the one with the best representation for searching elements of S. Because of this, it is called the Optimal Binary Search Tree.

 

Input

The input will contain several instances, one per line.

Each line will start with a number 1 ≤ n ≤ 250, indicating the size of S. Following n, in the same line, there will be n non-negative integers representing the query frequencies of the elements of S: f(e1), f(e2), . . . , f(en), 0 ≤ f(ei) ≤ 100. Input is terminated by end of file.

Output

For each instance of the input, you must print a line in the output with the total cost of the Optimal Binary Search Tree.

 

Sample Input

1 5

3 10 10 10

3 5 10 20

Sample Output

0

20

20

 

posted on 2019-08-06 18:39  好吧,就是菜菜 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/shuiyonglewodezzzzz/p/11311004.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值