• 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;
    }


  • 相关阅读:
    正则表达式常用语法
    JDK源码分析hashmap
    追加数据
    验证域名!!!!!!!!!
    Hadoop(一)之初识大数据与Hadoop
    Hadoop(十)Hadoop IO之数据完整性
    Hadoop(九)Hadoop IO之Compression和Codecs
    Hadoop(八)Java程序访问HDFS集群中数据块与查看文件系统
    Hadoop(七)HDFS容错机制详解
    python连接数据库
  • 原文地址:https://www.cnblogs.com/riskyer/p/3395438.html
Copyright © 2020-2023  润新知