考试总结T2(接上次整的T1)
首先说一句,树的每个元素的名称的问题,(那个叫jie点的东西)
具体是节点还是结点...baidu百科写的是结点...
本文章将不考虑到底这俩字怎么写...所以两种都可能出现
T2描述:
扶苏翻遍了歌单却没有找到一首歌能做这个题的题目背景,于是放上了扶苏最喜欢的一首《不老梦》.
与Day1的第二题一样,今天的第二题依然是一道树论题.
我们定义一棵\(n\)个节点的树为一个有\(n\)个节点和\(n-1\)条边的无向连通图.
如果我们定义\(u\)是一颗树\(T\)的根,那么任意一个节点\(v\)到根的路径就是从\(v\)出发到达点\(u\)的简单路径上所经过的点的点集。可以证明这样的简单路径有且仅有一条
定义一个节点\(x\)是节点\(y\)的孩子,当且仅当\(x\)和\(y\)之间有边相连且\(x\)不在\(y\)到根的路径中。如果\(x\)是\(y\)的孩子,那么定义\(y\)是\(x\)的家长节点.
如果我是_rqy那种毒瘤神仙的话,可能会问你每个节点的孩子数不超过\(k\)的\(n\)个节点的带标号无根树一共有多少个,可惜这个问题我也不会,所以我不会问你这么毒瘤的问题.
扶苏从一颗\(n\)个节点的树的1号节点出发,沿着树上的边行走。当然我们约定1号节点是这棵树的根。他所行走的规定是:当扶苏在点 \(u\)时,扶苏要么在\(u\)的孩子中选择一个没有到达过得点\(v\)并行走到\(v\),要么选择回到\(u\)的家长节点.
现在给每个节点一个权值\(w\),其中i 号节点的权值为\(w_i\)。扶苏有一些石子,他想给这棵树上的某一个节点放上石子。我们规定扶苏能在节点\(u\)放上石子当且仅当满足如下条件:
1、扶苏当前在节点\(u\)
2、对于\(u\)的所有孩子节点\(v\),节点\(v\)被放上了\(w_v\) 颗石子。
但是,扶苏在任意时刻都可以取回任意节点的石子。
现在,扶苏想问问你对于每个节点,如果他想在i 号节点上放\(w_i\)颗石子,那么他一开始需要准备多少石子.
有人说T3比T2简单,然而我在考场上对于T2更有思路...
今天大佬在讲题时跟我的思路大致一致(woc大致一致!!!!)
分析思路:
由题可知,要拿到整体最优需要考虑前面的石子如何才能充分利用
我们知道前面节点的石子能够利用的条件是当前处理子节点的几个儿子节点已满并且孙子节点非空,再且就是当其同辈节点已经填上石子的情况下,将其孩子节点进行"剥削",将其石子取走,
现在难免要面对这么一个问题:
在处理某一个节点(就是同辈节点)的最小花费时,如何安排顺序才能致使结果最优呢?
现在考虑一层有\(n\)个节点,其中该层节点本身需要的石子数先不考虑,只考虑其
因为现在我们考虑每个节点处理的顺序的原因是要考虑对其子节点所含石子的利用,
就是要考虑哪个节点的子节点所含石子在填满(满足填该节点本身)并且该节点已经填了石子时,其子节点的石子可以拿出来用,
那么如果当前节点的子节点石子较多,在把此节点的石子填上以后,可重复利用的石子也较多
举个栗子啦....
如图:
现在假如4 5节点需要8个石子,6 7节点需要90个石子,2节点需要2个石子,3节点需要10个石子,
分两种情况讨论:
1.先填2节点(意味着先填满4 5节点)
那么先取8+2个石子填满2,4,5节点,现在可以拿出2号节点的子节点中所有石子(当然2节点不能取)来填3号及其子节点,那么取下面的8个石子,现在右边需要的总共100个石子中填了8个,还需另外92个石子,只能再次造成花费,添加石子,此时显然造成了极大浪费,需要使用108个石子.
2.先填3节点
先取100个石子填3号及其子节点,辣么那么现在的花费是100,再同样将3号的子节点石子取出利用,填2号等,此时我们发现这90个剩余石子不仅能够完成填满2号及其子节点的任务,还能去填1号节点或是2,3号的兄弟节点,(仅在这棵确定的二叉树下)对于填满2,3所在层,仅需石子100枚(怎么量词突然正经?)
通过以上案例模拟易知,也可推知,在处理某层节点时,需要先处理子节点所含石子多的,
(当时考虑暴搜来着,实际就是暴搜,然而并不会处理变量关系...)
再同样的复读一遍给出公式推导与证明:
设本层有两个节点\(i\)与\(j\),设其子节点所含石子总数为\(a_i\)与\(a_j\),
其本身的花费为\(w_i\)与\(w_j\),现在令\(a_i>a_j\)
则有:
先买\(i\)的花费是\(max(w_i+a_i,w_i+w_j+a_j)\)
同理先买\(j\)的花费是\(max(w_j+a_j,w_j+w_i+a_i)\)
化简得这样两个式子:
\(w_i+max(a_i,w_j+a_j)\)
\(w_j+max(a_j,w_i+a_i)\)
展开式子:
1式有两种情况:
\(w_i+a_i\)或\(w_i+w_j+a_j\)
然而第二个铁定只有一种:
\(w_j+a_i+w_i\), 因为\(a_i\)始终大于\(a_j\)
作差一减便知,无论如何二式减一式总大于等于零,
所以无论如何选\(a_{较大的那个}\)总是最优方案,扩展一下会发现这是无论树高的统一结论,
现在剩下所要做的就是搜索!!
现在需要注意几点:
1.考虑的处理顺序序列其实是不上升序列而非递减序列,因为可以有相等的情况出现...
2.在进行深搜时,如果一个个跑一边就显得太蠢了,不如在每次递归处理子节点时将节点按此规则排序,这也是一种优化的方案, 不然会丢30分(一个点30分)
没亲测,但有效~
代码贴上(又是好神奇的二空格首行缩进,这就是强者的世界嘛?):
#include <cstdio>
#include <vector>
#include <algorithm>
const int maxn = 100010;
int n;
int MU[maxn], ans[maxn];
std::vector<int>son[maxn];
void dfs(const int u);
bool cmp(const int &_a, const int &_b);
int main() {
freopen("yin.in", "r", stdin);
freopen("yin.out", "w", stdout);
scanf("%d", &n);
for (int i = 2, x; i <= n; ++i) {
scanf("%d", &x);
son[x].push_back(i);
}
for (int i = 1; i <= n; ++i) {
scanf("%d", MU + i);
}
dfs(1);
for (int i = 1; i < n; ++i) {
printf("%d ", ans[i]);
}
printf("%d\n", ans[n]);
return 0;
}
void dfs(const int u) {
for (auto v : son[u]) {
dfs(v);
}
std::sort(son[u].begin(), son[u].end(), cmp);
int _ret = 0;
for (auto v : son[u]) {
if (_ret >= ans[v]) {
_ret -= ans[v];
} else {
ans[u] += ans[v] - _ret;
_ret = ans[v] - MU[v];
}
}
ans[u] += std::max(0, MU[u] - _ret);
}
inline bool cmp(const int &_a, const int &_b) {
return (ans[_a] - MU[_a]) > (ans[_b] - MU[_b]);
}
考试总结T2(接上次整的T1)的更多相关文章
- 三个线程T1,T2,T3.保证顺序执行的三种方法
经常看见面试题:有三个线程T1,T2,T3,有什么方法可以确保它们按顺序执行.今天手写测试了一下,下面贴出目前想到的3种实现方式 说明:这里在线程中我都用到了sleep方法,目的是更容易发现问题.之前 ...
- C# Tuple<T1,T2....T>元组的使用
1) 先说组元:一个数据结构,由通过逗号分割的,用于传递给一个程序或者操作系统的一系列值的组合. NET Framework 直接支持一至七元素的元组 Tuple<T1> Tuple< ...
- Tuple<T1,T2,.........T> 元组简单使用
元组:一个数据结构,逗号分隔,用于传递一个程序或者操作系统的一系列值得组合 NET Framework直接支持一至七元素得数组 Tuple<T1> Tuple<T1,T2> T ...
- [程序员代码面试指南]二叉树问题-判断t1树是否包含t2树的全部拓扑结构、[LeetCode]572. 另一个树的子树
题目1 解 先序遍历树1,判断树1以每个节点为根的子树是否包含树2的拓扑结构. 时间复杂度:O(M*N) 注意区分判断总体包含关系.和判断子树是否包含树2的函数. 代码 public class Ma ...
- [考试反思]1026csp-s模拟测试88:发展
不用你们说,我自己来:我颓闪存我没脸. 昨天的想法, 今天的回答. 生存, 发展. 总分榜应该稍有回升,但是和上面的差距肯定还是很大. 继续. 为昨天的谬误,承担代价. T2和T3都值得张记性. T2 ...
- NOI2015考试小结
这次NOI2015有幸获得金牌考进了国家集训队,意味着我的OI退役时间既省选之后有延迟了好几个月,又有了新的目标吧. 先说一下考试之外的感受吧,学军宿舍很牛X,接待NOIers而不提供插座,唯一可以用 ...
- 2019.3.18考试&2019.3.19考试&2019.3.21考试
2019.3.18 C O D E T1 树上直接贪心,环上for一遍贪心 哇说的简单,码了将近一下午终于码出来了 感觉自己码力/写题策略太糟糕了,先是搞了一个细节太多的写法最后不得不弃疗了,然后第二 ...
- [考试反思]0919csp-s模拟测试47:苦难
ISOLATION 也不粘上面的了,先管好自己. 附了个近期总分,可以看出什么. 反思一下考试心态: 开场看题目,T1傻逼题不用脑子,T2傻逼板子,T3... 这T3是啥啊?没看懂题目啊?再看一遍.啥 ...
- [考试反思]0809NOIP模拟测试15:解剖
说在前面: 不建议阅读.这里没有考试经验,只有一大堆负面情绪. 看了你不会有什么收获.看完了就不要怪我影响了你的心情. 以后不粘排行榜了.没什么意思没什么用. 但是我的意思并不是因为这次没考好的一时兴 ...
随机推荐
- Spring Batch基本概念
Spring batch主要有以下部分组成: JobRepository 用来注册job的容器 JobLauncher 用来启动Job的接口 Job ...
- bzoj3293 分金币
题目链接 problem 圆桌上坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一些金币,最终使 得每个人的金币数目相等.你的任务是求出被转手的金币数量的最小值. so ...
- Python GUI教程一:Hello World
STEP 1:PyQt5基本介绍 Qt是GUI编程中非常受欢迎,也是非常强大的一个工具. PyQt5 是Qt的Python版本.它大概涵盖了620个类,6000多个函数.PyQt5进行双重许可,开发者 ...
- Java中Set与Set<?>到底区别在哪?
您可能知道,无界通配符 Set<?> 可以容纳任何类型的元素,而原始类型Set也可以容纳任何类型的元素.那它们之间有什么区别呢? 1.关于Set<?>的两个事实 关于Set&l ...
- 【raid级别】RAID级别工作模式
友情链接 磁盘分区,格式化,挂载,创建交换分区:https://www.cnblogs.com/HeiDi-BoKe/p/11936998.html RAID工作级别:https://www.cnbl ...
- vsc 自定义快速生成vue模板
1.安装vscode 官网地址:https://code.visualstudio.com/ 2.安装一个插件,识别vue文件 插件库中搜索Vetur,下图中的第一个,点击安装,安装完成之后点击重新加 ...
- commonDispatchException 函数的逆向
看书中给出的内容: 1:在栈中构建 EXCEPTION_RECORD 结构体 2. 根据函数传递参数逆推得到 "判断先前模式"的反汇编代码
- Android Studio 提高开发效率的插件
好久没有更新博客了,最近搞个listview搞得半死不活的,心累~~ 今天带来的是Android Studio插件的整理,全是我已经安装使用的,写这篇博文的目的也是因为我怕我自己给忘记怎么用(尴尬) ...
- MySQL 联表查询
关系型数据库,免不了表之间存在各种引用与关联.这些关联是通过主键与外键搭配来形成的.所以,取数据时,很大情况下单张表无法满足需求,额外的数据则需要将其他表加入到查询中来,这便是 JOIN 关键字完成的 ...
- python3的reload(sys)
import sys reload(sys) sys.setdefaultencoding(‘utf-8’) 以上是python2的写法,但是在python3中这个需要已经不存在了,这么做也不会什么实 ...