zoukankan      html  css  js  c++  java
  • 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;
    }


  • 相关阅读:
    Mysql 存储过程小例子
    Notepad++ 运行脚本快捷键设置
    Review PHP设计模式之——观测模式
    Review PHP设计模式之——注册模式
    2018年5月6日GDCPC(广东赛区)总结
    套题总结
    2017年广东省ACM省赛(GDCPC-2017)总结
    在线购物系统 实验五设计类
    在线购物系统 实验一问题描述、词汇表
    ACM ICPC 2011-2012 Northeastern European Regional Contest(NEERC)G GCD Guessing Game
  • 原文地址:https://www.cnblogs.com/riskyer/p/3395438.html
Copyright © 2011-2022 走看看