【DP】【P4539】 [SCOI2006]zh_tree
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
其实就是推式子啦……
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\) 中提出来
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的更多相关文章
- T2980 LR棋盘【Dp+空间/时间优化】
Online Judge:未知 Label:Dp+滚动+前缀和优化 题目描述 有一个长度为1*n的棋盘,有一些棋子在上面,标记为L和R. 每次操作可以把标记为L的棋子,向左移动一格,把标记为R的棋子, ...
- 【10.3校内测试【国庆七天乐!】】【DP+组合数学/容斥】【spfa多起点多终点+二进制分类】
最开始想的暴力DP是把天数作为一个维度所以怎么都没有办法优化,矩阵快速幂也是$O(n^3)$会爆炸. 但是没有想到另一个转移方程:定义$f[i][j]$表示每天都有值的$i$天,共消费出总值$j$的方 ...
- 【DP+树状数组】BZOJ1264-[AHOI2006]基因匹配Match
[题目大意] 给定n个数和两个长度为n*5的序列,两个序列中的数均有1..n组成,且1..n中每个数恰好出现5次,求两个序列的LCS. [思路] 预处理每个数字在a[i]中出现的五个位置.f[i]示以 ...
- BZOJ1079 [SCOI2008]着色方案 【dp记忆化搜索】
题目 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+-+ck=n.相邻两个木块涂相同色显得很难看 ...
- 【DP|多重背包可行性】POJ-1014 Dividing
Dividing Time Limit: 1000MS Memory Limit: 10000K Description Marsha and Bill own a collection of mar ...
- COGS 862. 二进制数01串【dp+经典二分+字符串】
862. 二进制数01串 ★ 输入文件:kimbits.in 输出文件:kimbits.out 简单对比 时间限制:1 s 内存限制:128 MB USACO/kimbits(译 by ...
- CodeForces - 597C Subsequences 【DP + 树状数组】
题目链接 http://codeforces.com/problemset/problem/597/C 题意 给出一个n 一个 k 求 n 个数中 长度为k的上升子序列 有多少个 思路 刚开始就是想用 ...
- hihocoder1475 数组分拆【DP+前缀和优化】
思路: DP[ i ] 代表以 i 结尾的方案数. dp[i] += sum[i] - sum[j - 1] != 0 ? dp[j] : 0 ; 对于100%的数据,满足1<=N<=10 ...
- SPOJ130 【DP·背包选取特性】
题意: 给你n个任务,每个任务有一个起始时间,持续时间,一个权值: 问你怎么分配得到最大值 思路: 数据好大..百度了一发意识到自己好菜啊!背包的特性. dp[i]代表前 i 个能构成的最大值. 对于 ...
- lightoj1145 【DP优化求方案】
题意: 有一个k面的骰子,然后问你n个骰子朝上的面数字之和=s的方案: 思路: dp[i][j] 代表 前 i 个骰子组成 j 有多少种方案: 显然 dp[i][j] = dp[i - 1][j - ...
随机推荐
- aircrack-ng无线破解实验
查看无线网卡 airmon-ng 开启网卡监听模式 airmon-ng start wlan0 扫描附近的wifi airodump-ng wlan0mon 停止扫描: ctrl c 使用airodu ...
- API验证
API验证说明 API验证: a. 发令牌: 静态 PS: 隐患 key被别人获取 b. 动态令牌 PS: (问题越严重)用户生成的每个令牌被黑客获取到,都会破解 c. 高级版本 PS: 黑客网速快, ...
- Vue 事件处理
原生的js事件处理 原生的js事件处理,可以分为:直接内联执行代码,或者绑定事件函数. 在内联的事件处理函数内部或者事件绑定的方法内部的作用域中的this都是指向当前的dom对象.如何在vue绑定的元 ...
- sprint2(第四天)
由于最近网络不行,更新的代码push不上Github,组员之间又不能clone得到最新的项目,所以这几天都没有更新到Github 燃尽图
- 基于NABCD评论作业-王者荣耀交流协会PSP DAILY
一.根据(不限于)NABCD评论作品的选题 N(Need,需求):在我知道PSP DAILY这款软件的时候,就认为这款软件对于学习软件工程课的学生来说有很大的需要.对于需求来说,软件工程课程中的学 ...
- 10.29 scrum meeting newbe软件团队工作分配
这次会议,我们主要讨论了目前阶段的主要任务与任务分配问题. 首先,通读代码,理解程序的运行方式是必不可少的环节.所以我们要求团队的所有成员通读代码.并且对于开发人员和测试人员,要求写出我们分配的各自模 ...
- OO学习体会与阶段总结(设计与实现)
前言 在最近的一个月的课程中,笔者对于规格化编程进行了深入的学习.运用面向对象抽象思想对编写的程序进行过程抽象.异常处理.数据抽象.类的层次规格与迭代等等规格设计,使得程序结构化程度提高,具有更好 ...
- IO异常 的处理
package com.throwsss; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFou ...
- spring时间管理
spring时间管理相比Quartz要简单的多,但功能不如quartz强大 spring.xml的配置 <?xml version="1.0" encoding=" ...
- 使用 Vagrant 打造跨平台开发环境fffff
Vagrant 是一款用来构建虚拟开发环境的工具,非常适合 php/python/ruby/java 这类语言开发 web 应用,“代码在我机子上运行没有问题”这种说辞将成为历史. 我们可以通过 Va ...