Description

张老师根据自己工作的需要,设计了一种特殊的二叉搜索树。

他把这种二叉树起名为zh_tree,对于具有n个结点的zh_tree,其中序遍历恰好为(1,2,3,…,n),其中数字1,2,3,…,n 是每个结点的编号。n个结点恰好对应于一组学术论文中出现的n个不同的单词。

第 \(j\) 个单词在该组论文中出现的次数记为 \(j\),例如,\(d_2~=~10\) 表示第 \(2\) 个结点所对应的单词在该组论文中出现了 \(10\) 次。设该组论文中出现的单词总数为 \(S\) ,显然,\(S~=~\sum_{i = 1}^{n} d_i\)。记 \(f_i~=~\frac{d_i}{s}\) 为第j个单词在该组论文中出现的概率(频率)。

张老师把根结点深度规定为 \(0\) ,如果第 \(j\) 个结点的深度为 \(r\) ,则访问该结点 \(j\) 的代价 \(h_j\) 为 \(h_j~=~k(r + 1)~+~c\),其中\(k,c\)为已知的不超过100的正常数。

则zh_tree是满足以下条件的一棵二叉树:\(\sum_{i = 1}^n f_i h_i\) 达到最小。

我们称上式为访问zh_tree的平均代价。 请你根据已知数据为张老师设计一棵zh_tree。

Input

第1行:3个用空格隔开的正数: n k c 其中n<30,为整数,k,c为不超过100的正实数。 第2行:n个用空格隔开的正整数,为每个单词出现的次数(次数<200)。

Output

输出一行表示最小平均代价

Hint

\(1~\leq~n~\leq~30~,~0~\leq~d_i~\leq~200​\)

Solution

其实就是推式子啦……

\[\begin{align}
ans~
& =~\min~\{~\sum_{i = 1}^{n} h_i~\times~f_i\}\\
& =~\min~\{\sum_{i = 1}^n~h_i~\times~\frac{d_i}{S}\}\\
& =~\min~\{\frac{1}{S}~\times~sum_{i = 1}^n~h_i~\times~d_i\}\\
& =~\min~\{\frac{1}{S}~\times~\sum_{i = 1}^n~[k~(r_i~+~1)~c]~\times~d_i\\
& =~\min~\{\frac{1}{S}~\times~\sum_{i = 1}^n~[k~(r_i~+~1)~d_i]~+~\sum_{i = 1}^n d_i~\times~c\}\\
& =~\min~\{\frac{1}{S}~\times~k~\sum_{i = 1}^n~[(r_i~+~1)~d_i]~+~S~\times~c\}\\
\end{align}\]

然后我们发现 \(S~=~\sum_{i = 1}^n d_i\) 是个常数,\(c\) 也是一个常数,我们将只与这两个值有关的项从 \(\min\) 中提出来

\[\begin{align}
ans~
& =~\frac{1}{S}~+~S~\times~c~+~\min\{k~\sum_{i = 1}^n~(r_i~+~1)~d_i\}\\
& =~\frac{1}{S}~+~S~\times~c~+~k~\times~\min\{\sum_{i = 1}^n~(r_i~+~1)~d_i\}
\end{align}\]

于是我们发现我们事实上要最小化 \(\sum_{i = 1}^n~(r_i~+~1)~d_i\),同时满足在这棵树上的中序遍历是 \(1~\sim~n\)

由于中序遍历的顺序是“左中右”,所以我们可以直接设 \(f_{l,r}\) 为区间 \([l,r]\) 的中序遍历为 \(l~\sim~r\) 时上式的最小值,转移时可以枚举一个点 \(i\) 作为根,则左右子树显然要从上式最小的树形转移过来。转移时等价于左右子树每个点的树高都增加 \(1\),即对答案的贡献增加 \(\sum_{j = l}^{i - 1} d_j~+~\sum_{j = i + 1}^{r} d_j\)。然后加上根的贡献 \(d_i\),所以增加的贡献即为 \(\sum_{j = l}^r d_j\)。直接使用前缀和优化该式子即可。

最后计算答案时记得将常数项乘上。复杂度 \(O(n^3)\)。

Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#endif
#define rg register
#define ci const int
#define cl const long long typedef long long int ll; namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
} template <typename T>
inline void qr(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
} template <typename T>
inline void ReadDb(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
if (ch == '.') {
ch = IPT::GetChar();
double base = 1;
while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
}
if (lst == '-') x = -x;
} namespace OPT {
char buf[120];
} template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
rg int top=0;
do {OPT::buf[++top] = x % 10 + '0';} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
} const int maxn = 35; int n;
double c, k;
double MU[maxn], frog[maxn][maxn], sum[maxn]; int main() {
freopen("1.in", "r", stdin);
qr(n); ReadDb(k); ReadDb(c);
memset(frog, 127, sizeof frog);
for (rg int i = 1; i <= n; ++i) {
ReadDb(sum[i]);
frog[i][i] = sum[i]; frog[i + 1][i] = 0;
sum[i] += sum[i - 1];
}
frog[1][0] = 0;
for (rg int len = 1; len < n; ++len) {
for (rg int l = 1; l < n; ++l) {
int r = l + len;
if (r > n) break;
for (rg int i = l; i <= r; ++i) frog[l][r] = std::min(frog[l][r], frog[l][i - 1] + frog[i + 1][r]);
frog[l][r] += sum[r] - sum[l - 1];
}
}
printf("%.3lf\n", (k * frog[1][n] + sum[n] * c) / sum[n]);
}

Summary

二叉树的中序遍历是 左中右 不是 中左右

【DP】【P4539】 [SCOI2006]zh_tree的更多相关文章

  1. T2980 LR棋盘【Dp+空间/时间优化】

    Online Judge:未知 Label:Dp+滚动+前缀和优化 题目描述 有一个长度为1*n的棋盘,有一些棋子在上面,标记为L和R. 每次操作可以把标记为L的棋子,向左移动一格,把标记为R的棋子, ...

  2. 【10.3校内测试【国庆七天乐!】】【DP+组合数学/容斥】【spfa多起点多终点+二进制分类】

    最开始想的暴力DP是把天数作为一个维度所以怎么都没有办法优化,矩阵快速幂也是$O(n^3)$会爆炸. 但是没有想到另一个转移方程:定义$f[i][j]$表示每天都有值的$i$天,共消费出总值$j$的方 ...

  3. 【DP+树状数组】BZOJ1264-[AHOI2006]基因匹配Match

    [题目大意] 给定n个数和两个长度为n*5的序列,两个序列中的数均有1..n组成,且1..n中每个数恰好出现5次,求两个序列的LCS. [思路] 预处理每个数字在a[i]中出现的五个位置.f[i]示以 ...

  4. BZOJ1079 [SCOI2008]着色方案 【dp记忆化搜索】

    题目 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+-+ck=n.相邻两个木块涂相同色显得很难看 ...

  5. 【DP|多重背包可行性】POJ-1014 Dividing

    Dividing Time Limit: 1000MS Memory Limit: 10000K Description Marsha and Bill own a collection of mar ...

  6. COGS 862. 二进制数01串【dp+经典二分+字符串】

    862. 二进制数01串 ★   输入文件:kimbits.in   输出文件:kimbits.out   简单对比 时间限制:1 s   内存限制:128 MB USACO/kimbits(译 by ...

  7. CodeForces - 597C Subsequences 【DP + 树状数组】

    题目链接 http://codeforces.com/problemset/problem/597/C 题意 给出一个n 一个 k 求 n 个数中 长度为k的上升子序列 有多少个 思路 刚开始就是想用 ...

  8. hihocoder1475 数组分拆【DP+前缀和优化】

    思路: DP[ i ] 代表以 i 结尾的方案数. dp[i] += sum[i] - sum[j - 1] != 0 ? dp[j] : 0 ; 对于100%的数据,满足1<=N<=10 ...

  9. SPOJ130 【DP·背包选取特性】

    题意: 给你n个任务,每个任务有一个起始时间,持续时间,一个权值: 问你怎么分配得到最大值 思路: 数据好大..百度了一发意识到自己好菜啊!背包的特性. dp[i]代表前 i 个能构成的最大值. 对于 ...

  10. lightoj1145 【DP优化求方案】

    题意: 有一个k面的骰子,然后问你n个骰子朝上的面数字之和=s的方案: 思路: dp[i][j] 代表 前 i 个骰子组成 j 有多少种方案: 显然 dp[i][j] = dp[i - 1][j - ...

随机推荐

  1. Digitalocean + ss 搭建加密通信代理服务器

    本文以 DigitalOcean + ss/ssr 配置加密通道***为例,记录了手动搭梯子的过程. 启动一个服务器实例的操作可以参考我的这篇博文,这里主要介绍 ss/ssr 的服务搭建过程. 首先 ...

  2. centos7安装oracle的一些问题

    在配置监听的时候尝试了很多次都是不能创建,最后将 /data/oracle/product/11.2.0/db_1/network/admin目录下的listener.ora和tnsname.ora两 ...

  3. 实验1 熟悉Linux开发环境 实验报告

    参见http://www.cnblogs.com/lhc-java/p/4970269.html

  4. Java程序设计基础项目总结报告

    Java程序设计基础项目总结报告 20135313吴子怡 一.项目内容 运用所学Java知识,不调用Java类库,实现密码学相关算法的设计,并完成TDD测试,设计运行界面. 二.具体任务 1.要求实现 ...

  5. java的小学生四则运算

    import java.awt.*; import java.awt.event.*; import java.io.FileNotFoundException; import java.io.IOE ...

  6. Internet History, Technology and Security (Week3)

    Week3. Welcome to week 3! This is our fourth and final week of History where we make the connection ...

  7. NodeJs异步的执行过程

    我这里写了一个代码片段,用来模拟一个嵌套的异步过程,下面我总结了下这段代码的执行顺序var fs = require("fs"); fs.stat('a.txt',callback ...

  8. 0506-Scrum 项目 2.0视频

    一.团队项目要求 应用NABCD模型,分析你们初步选定的项目,充分说明你们选题的理由. 录制为演说视频,上传到视频网站,并把链接发到团队博客上. 二.NABCD模型 选题:约拍平台——家教平台 1) ...

  9. PAT 1078 字符串压缩与解压

    https://pintia.cn/problem-sets/994805260223102976/problems/994805262018265088 文本压缩有很多种方法,这里我们只考虑最简单的 ...

  10. cxGrid使用汇总

    1.自动行高:CellAutoHeight(单元自动高度)设置为True. procedure <AForm>.<AGridColumn>PropertiesValidate( ...