「 洛谷 」P4539 [SCOI2006]zh_tree
小兔的话
推荐 小兔的CSDN
[SCOI2006]zh_tree
题目限制
- 内存限制:250.00MB
- 时间限制:1.00s
- 标准输入输出
题目知识点
- 思维
- 动态规划 \(dp\)
- 区间\(dp\)
题目来源
为了方便大家阅读通畅,题目可能略有改动,保证不会造成影响
题目
题目背景
张老师根据自己工作的需要,设计了一种特殊的二叉搜索树
题目描述
他把这种二叉树起名为 zh_tree,对于具有 \(n\) 个节点的 zh_tree,其中序遍历恰好为 \((1、2、3、···、n)\),其中数字 \(1、2、3、···、n\) 是每个节点的编号
\(n\) 个结点恰好对应于一组学术论文中出现的 \(n\) 个不同的单词
第 \(i\) 个单词在该组论文中出现的次数记为 \(d_i\),例如,\(d_2 = 10\) 表示第 \(2\) 个节点所对应的单词在该组论文中出现了 \(10\) 次
设该组论文中出现的单词总数为 \(S\),即 \(S = d_1 + d_2 + ··· + d_n = \sum _{i = 1} ^{n} d_i\)
记 \(f_i = \frac{d_i}{S}\) 为第 \(i\) 个单词在该组论文中出现的 概率(频率)
张老师把根节点深度规定为 \(0\),如果第 \(i\) 个节点的深度为 \(r_i\),则访问该节点的代价为 \(h_i\),\(h_i = k(r_i + 1) + c\),其中 \(k、c\) 为已知的常数 \((0 < k, c \leq 100)\)
则 zh_tree 是满足 \(h_1f_1 + h_2f_2 + ··· + h_nf_n = \sum _{i = 1} ^ {n} h_if_i\) 最小的一棵二叉树
我们称上式为访问 zh_tree 的代价
请你根据已知的数据为张老师设计一棵 zh_tree
格式
输入格式
输入共 \(2\) 行:
对于第 \(1\) 行,\(3\) 个用空格隔开的正数,\(n、k、c\)。其中 \(n < 30\),为整数;\(k、c\) 为不超过 \(100\) 的正实数
对于第 \(2\) 行:\(n\) 个用空格隔开的正整数,为每个单词出现的次数 \(d_i(d_i < 200)\)
输出格式
输出一行:一个正实数,保留 \(3\) 位小数,表示访问 zh_tree 的最小代价
样例
样例输入
4 2 3.5
20 30 50 20
样例输出
7.000
提示
数据范围
对于 \(100\%\) 的数据:\(1 \leq n < 30\),\(0 < k、c \leq 100\),\(d_i < 200\)
思路
对于每个节点的深度 \(r_i\),由于 \(h_i = k(r_i + 1) + c\),不妨可以把根节点的深度改为 \(1\),这样就可以直接用 现在的 \(r_i\) 表示 原来的 \(r_i + 1\) 了
我们可以先把 \(\sum _{i = 1} ^ {n} h_if_i\) 化简
\(\sum _{i = 1} ^ {n} (h_i * f_i) = \sum _{i = 1} ^{n} [k(r_i + c) * \frac{d_i}{S}] = k * \frac{1}{S} * \sum _{i =1} ^{n} [(r_i + c) * d_i] = \frac{k}{S} * \sum _{i = 1} ^{n} (r_i * d_i + c * d_i) = \frac{k}{S} * (\sum _{i = 1} ^{n} r_i * d_i + \sum _{i = 1} ^{n} c * d_i) = (\frac{k}{S} * \sum _{i = 1} ^{n} r_i * d_i) + [\frac{k}{S} * c * \sum _{i = 1} ^{n} d_i] = (\frac{k}{S} * \sum _{i = 1} ^{n} r_i * d_i) + [\frac{k}{S} * c * S] = k * [\frac{\sum _{i = 1} ^{n} r_i * d_i}{S} + c]\)
题目要我们求 \(\sum _{i = 1} ^ {n} h_if_i\) 的最小值,就可以转化成求 \(\sum _{i = 1} ^{n} r_i * d_i\) 的最小值了
这道题也就是道 区间 \(dp\) 的题目了
分析
设 \(dp[i][j]\) 表示:一棵二叉树的 中序遍历(左子树,根节点,右子树) 为 \((i、i + 1、i + 2、···、j)\) 时,\(\sum _{k = i} ^{j} r_k * d_k\) 的最小值
最终的答案就是 \(\frac{K * dp[1][n]}{S} + C\) 了
首先,对于每个 \(k = i = j\),\(dp[k][k] = r_k * d_k\);而其它的每个 \(i \neq j\),值则为 \(INF\),即无穷大 —— 这是初始状态
其次,每个 \(dp[i][j] (i < j)\) 是由上一个状态转移而来的,我们可以用 \(k\) 来枚举每一个可能的子树根节点 \(->\) 就得到由 \(k\) 分成的左子树和右子树了,由于要生成新的一棵二叉树,左右子树每个节点的深度需要加 \(1\),贡献就是 \((\sum _{t = i} ^{k - 1} d_t) + (\sum _{t = k + 1} ^{j} d_t)\);同时还有当前 \(k\) 节点的贡献 \(d_k\);总贡献就是 \(\sum _{t = i} ^{j} d_t\)
所以 \(dp[i][j] = \min\{dp[i][k - 1] + dp[k + 1][j] + \sum _{t = i} ^{j} d_t\}\)
不过,需要在 \(k = i\) 或 \(k = j\) 的时候特殊处理
代码
#include <cstdio>
#include <cstring>
#define Min(a, b) ((a) < (b) ? (a) : (b))
const int MAXN = 30;
int N, S;
int D[MAXN + 5];
int Pre[MAXN + 5];
double K, C;
double dp[MAXN + 5][MAXN + 5];
int main()
{
memset(dp, 0x3f, sizeof(dp));
scanf("%d %lf %lf", &N, &K, &C);
for (int i = 1; i <= N; i++)
{
scanf("%d", &D[i]);
Pre[i] = S += D[i];
dp[i][i] = 1.0 * D[i];
}
for (int len = 2; len <= N; len++)
{
for (int i = 1, j = len; j <= N; i++, j++)
{
dp[i][j] = Min(dp[i][j - 1], dp[i + 1][j]);
for (int k = i + 1; k <= j - 1; k++)
dp[i][j] = Min(dp[i][j], dp[i][k - 1] + dp[k + 1][j]);
dp[i][j] += 1.0 * (Pre[j] - Pre[i - 1]);
}
}
printf("%.3lf\n", K * dp[1][N] / S + C);
return 0;
}
「 洛谷 」P4539 [SCOI2006]zh_tree的更多相关文章
- 「 洛谷 」P2768 珍珠项链
珍珠项链 题目限制 内存限制:125.00MB 时间限制:1.00s 标准输入输出 题目知识点 动态规划 \(dp\) 矩阵 矩阵乘法 矩阵加速 矩阵快速幂 题目来源 「 洛谷 」P2768 珍珠项链 ...
- 「 洛谷 」P2151 [SDOI2009]HH去散步
小兔的话 欢迎大家在评论区留言哦~ HH去散步 题目限制 内存限制:125.00MB 时间限制:1.00s 标准输入 标准输出 题目知识点 动态规划 \(dp\) 矩阵 矩阵乘法 矩阵加速 矩阵快速幂 ...
- 「区间DP」「洛谷P1043」数字游戏
「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...
- 「P4994」「洛谷11月月赛」 终于结束的起点(枚举
题目背景 终于结束的起点终于写下句点终于我们告别终于我们又回到原点…… 一个个 OIer 的竞赛生涯总是从一场 NOIp 开始,大多也在一场 NOIp 中结束,好似一次次轮回在不断上演.如果这次 NO ...
- 「洛谷4197」「BZOJ3545」peak【线段树合并】
题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...
- 「洛谷3338」「ZJOI2014」力【FFT】
题目链接 [BZOJ] [洛谷] 题解 首先我们需要对这个式子进行化简,否则对着这么大一坨东西只能暴力... \[F_i=\sum_{j<i} \frac{q_iq_j}{(i-j)^2}-\s ...
- 「BZOJ2733」「洛谷3224」「HNOI2012」永无乡【线段树合并】
题目链接 [洛谷] 题解 很明显是要用线段树合并的. 对于当前的每一个连通块都建立一个权值线段树. 权值线段树处理操作中的\(k\)大的问题. 如果需要合并,那么就线段树暴力合并,时间复杂度是\(nl ...
- 「洛谷3870」「TJOI2009」开关【线段树】
题目链接 [洛谷] 题解 来做一下水题来掩饰ZJOI2019考炸的心情QwQ. 很明显可以线段树. 维护两个值,\(Lazy\)懒标记表示当前区间是否需要翻转,\(s\)表示区间还有多少灯是亮着的. ...
- 「洛谷5300」「GXOI/GZOI2019」与或和【单调栈+二进制转化】
题目链接 [洛谷传送门] 题解 按位处理. 把每一位对应的图都处理出来 然后单调栈处理一下就好了. \(and\)操作处理全\(1\). \(or\)操作处理全\(0\). 代码 #include & ...
随机推荐
- Spring中@Translational注解失效场景
今天面试被问到@Translational注解什么场景下失效,我一脸懵逼,说的恍恍惚惚的,下来我就总结一下@Translational注解失效的场景! @Transactional 注解相信大家并不陌 ...
- FairyGUI编辑器的和unity里的Obj对应关系
1.在FairyGUI官网上下载好unity的工程,用FairyGUI编辑器打开它的官方案例 2.在FairyGUI编辑器和Unity中,从一个最简单的示例"Bag"着手. ...
- 【建议收藏】阿里P7总结的Spring注解笔记,把组件注册讲的明明白白
环境搭建 注解的方式是通过配置类的方式来注入组件,注解注入要比XML注入的方式简单,注解注入也需要在前者的基础上,添加一个spring-context的包,也是实际开发中常用的方式. 准备所需Jar包 ...
- 厉害!这份阿里面试官 甩出的Spring源码笔记,GitHub上已经爆火
前言 时至今日,Spring 在 Java 生态系统与就业市场上,面试出镜率之高,投产规模之广,无出其右.随着技术的发展,Spring 从往日的 IoC 框架,已发展成 Cloud Native 基础 ...
- 这份java多线程笔记,你真得好好看看,我还没见过总结的这么全面的
1.线程,进程和多线程 1.程序:指指令和数据的有序集合,其本身没有任何意义,是一个静态的概念 2.进程:指执行程序的一次执行过程,是一个动态的概念.是系统资源分配的单位(注意:很多多线程是模拟出来的 ...
- zabbix的搭建及操作(3)监控 MySQL 及 HTTP 状态监控
书接上回 -- 详情点击 Server端以配置好 mariadb(MySQL) 及 http 服务 Zabbix实现监控 mysql 数据库 server服务器端配置 vim /usr/local/z ...
- 【VUE】7.组件通信(二)子组件修改父组件
1. 前提&知识点 1./components/Father.vue 是父组件, Son.vue 是子组件 2.子组件修改父组件 emit 2. 组件通信 1. 首先对子组件绑定一个事件 ch ...
- 自定义 JSTLFunction
复习常用JSTL Function为什么需要自定义Function如何自定义Function,例子:1.在独立的项目中(也可以在web项目中)的类中(比如Functions)编写一个static方法: ...
- linux(centos7.x)安装jdk
一.下载与安装 下载地址:链接:https://pan.baidu.com/s/1g7MF1xqlOxWnLGf2shl3NA 提取码:epae 下载完成后将安装包上传到linxu环境中,并将其 ...
- Linun中配置redis密码
这里以linux服务器为例,为redis配置密码. 1.第一种方式 (当前这种linux配置redis密码的方法是一种临时的,如果redis重启之后密码就会失效,) (1)首先进入redis,如果没有 ...