• uva 10304 Optimal Binary Search Tree(区间dp)


    Problem E

    Optimal Binary Search Tree

    Input: standard input

    Output: standard output

    Time Limit: 30 seconds

    Memory Limit: 32 MB

    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

    题意:给定n个结点的值,要求出由这些节点组成的最优二叉搜索树的最小值。

    思路:区间DP,dp[i][j]表示由i到j组成的树,k表示取根节点,所以如果k为根节点,那么i-k - 1和 k + 1-j 组成的树的层数将多一层,就多加一次值,所以状态转移方程为

    dp[i][j] = min{dp[i][j], dp[i][k - 1] + dp[k + 1][j] + value},然后开一个sum来保存和用于计算。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    
    int n, f[255], dp[255][255], sum[255];
    
    int main() {
        while (~scanf("%d", &n)) {
    	memset(sum, 0, sizeof(sum));
    	memset(dp, 0, sizeof(dp));
    	for (int i = 1; i <= n; i ++) {
    	    scanf("%d", &f[i]);
    	    sum[i] = sum[i - 1] + f[i];
    	}
    	for (int j = 2; j <= n; j ++) {
    	    for (int i = j - 1; i >= 0; i --) {
    		dp[i][j] = 999999999;
    		for (int k = i; k <= j; k ++) {
    		    dp[i][j] = min(dp[i][j], dp[i][k - 1] + dp[k + 1][j] + sum[j] - sum[i - 1] - f[k]);
    		}
    	    }
    	}
    	printf("%d
    ", dp[1][n]);
        }
        return 0;
    }


  • 相关阅读:
    基于Proxy的小程序状态管理
    还不会正则表达式?看这篇!
    Fundebug前端JavaScript插件更新至1.8.2,修复2个小BUG
    JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?
    5种处理Vue异常的方法
    重构:一项常常被忽略的基本功
    SQL Server中使用SQL语句关闭数据库连接和删除数据库文件
    SQL Server使用加密连接SSL/TLS (转载)
    SQL Server使用sp_executesql在存储过程中执行多个批处理
    How to call a stored procedure in EF Core 3.0 via FromSqlRaw(转载)
  • 原文地址:https://www.cnblogs.com/riskyer/p/3395438.html
Copyright © 2020-2023  润新知