文章目录
- T1 分析
- T2 分析
- T3 分析
T1 铺设道路
题目点击→洛谷 P5019 铺设道路 题目描述
春春是一名道路工程师,负责铺设一条长度为 nn 的道路。
铺设道路的主要工作是填平下陷的地表。整段道路可以看作是 块首尾相连的区域,一开始,第 块区域下陷的深度为
春春每天可以选择一段连续区间 ,填充这段区间中的每块区域,让其下陷深度减少 。在选择区间时,需要保证,区间内的每块区域在填充前下陷深度均不为
春春希望你能帮他设计一种方案,可以在最短的时间内将整段道路的下陷深度都变为
输入输出格式
输入格式:
输入文件包含两行,第一行包含一个整数 ,表示道路的长度。 第二行包含 个整数,相邻两数间用一个空格隔开,第 个整数为
输出格式:
输出文件仅包含一个整数,即最少需要多少天才能完成任务。
输入输出样例
输入样例#1:
6
4 3 2 5 3 5
输出样例#1:
9
【样例解释】
一种可行的最佳方案是,依次选择:、、、、、、、、。
【数据规模与约定】
对于 的数据, ;
对于 的数据, ;
对于 的数据,
T1 分析
常规送分题。考虑第一个位置的,这个位置是 ,那么这个位置必定要被填 次才能填平,然后考虑第二个位置,这个位置是 ,显然如果这个位置比 小,那么在填 的时候 也可以被填平,如果这个位置比 大,那么显然 中的 部分已经可以被填掉了,那么只要多加 次就可以填平 。
所以做法就出来了,从前往后填坑,保证到第 个位置的时候,前个都被填满了,那么显然第 个位置中高度为的部分是不需要被填的,只需要填超出的部分就可以了。
T2 货币系统
题目点击→洛谷 P5020 货币系统 题目描述
在网友的国度中共有 种不同面额的货币,第 种货币的面额为 ,你可以假设每一种货币都有无穷多张。为了方便,我们把货币种数为 、面额数组为 的货币系统记作 。
在一个完善的货币系统中,每一个非负整数的金额 都应该可以被表示出,即对每一个非负整数 ,都存在 个非负整数 满足 的和为 。然而, 在网友的国度中,货币系统可能是不完善的,即可能存在金额 不能被该货币系统表示出。例如在货币系统 , 中,金额
两个货币系统 和 是等价的,当且仅当对于任意非负整数 ,它要么均可以被两个货币系统表出,要么不能被其中任何一个表出。
现在网友们打算简化一下货币系统。他们希望找到一个货币系统 ,满足 与原来的货币系统 等价,且 尽可能的小。他们希望你来协助完成这个艰巨的任务:找到最小的 。
输入输出格式
输入格式:
输入文件的第一行包含一个整数 ,表示数据的组数。
接下来按照如下格式分别给出 组数据。 每组数据的第一行包含一个正整数 。接下来一行包含 个由空格隔开的正整数 。
输出格式:
输出文件共有 行,对于每组数据,输出一行一个正整数,表示所有与 等价的货币系统 中,最小的 。
输入输出样例
输入样例#1:
2
4
3 19 10 6
5
11 29 13 19 17
输出样例#1:
2
5
T2 分析
照例的简单题,普及组第2题到第3题的难度。
稍微估计一下分数区,纯暴力dfs应该可能只有15分,加上优化之类的奇奇怪怪的操作应该能到30分~40分。
当然如果意识到一个点:货币系统B一定是货币系统A的子集,也就是所有钱币的数量都来自于A集合,那么就算dfs应该也可以到达80分。
这里有一点,其实前50分的数据范围就是在提醒你是这件事了,小数据却是非常大的,大数据却变小 :
显然n小的数据通过放大来限制分数,因为你没有发现这道题需要你去发现的点,而发现了这个点的人一定可以通过前50分的数据,所以后50分就不再关注,当然这就是自己想想的…不要把这个当成判断题目做法的依据,这只能作为你让自己相信你的做法没有问题的一个非常小的理由。
如果发现了上面那个点,那就比较简单了,既然B一定是A的子集,那么只要去掉A中能被其他钱币组合出的钱币就可以了,也就是简化A,比如A中存在2 3 5三种钱币,显然5可以由2 + 3组成,那就不需要5了。
所以就是个简单的完全背包,标记一下哪些钱币能出现就可以了。
T3 赛道修建
题目点击→洛谷 P5021 赛道修建 题目描述
C 城将要举办一系列的赛车比赛。在比赛前,需要在城内修建
C 城一共有 个路口,这些路口编号为 ,有 条适合于修建赛道的双向通行的道路,每条道路连接着两个路口。其中,第 条道路连接的两个路口编号为 和 ,该道路的长度为 。借助这
一条赛道是一组互不相同的道路 ,满足可以从某个路口出发,依次经过 道路 (每条道路经过一次,不允许调头)到达另一个路口。一条赛道的长度等于经过的各道路的长度之和。为保证安全,要求每条道路至多被一条赛道经过。
目前赛道修建的方案尚未确定。你的任务是设计一种赛道修建的方案,使得修建的 条赛道中长度最小的赛道长度最大(即
输入输出格式
输入格式:
输入文件第一行包含两个由空格分隔的正整数
接下来 行,第 行包含三个正整数 ,表示第 条适合于修建赛道的道路连接的两个路口编号及道路长度。保证任意两个路口均可通过这
输出格式:
输出共一行,包含一个整数,表示长度最小的赛道长度的最大值。
输入输出样例
输入样例#1:
7 1
1 2 10
1 3 5
2 4 9
2 5 8
3 6 6
3 7 7
输出样例#1:
31
输入样例#2:
9 3
1 2 6
2 3 3
3 4 5
4 5 10
6 2 4
7 2 9
8 4 7
9 4 4
输出样例#2:
15
T3 分析
最后一题,需要一点思维性的东西。乍一眼一看就猜得出来肯定可以二分答案,那么问题就是check()怎么写了。
首先分析一下数据范围。
可以发现最显眼的一个条件就是
1、
解法:把所有边权记录下来,这种情况等价于将序列分割成 段,使
那么二分 段区间和的最小值,然后 贪心扫一遍,时间复杂度
2、 的情况
即这棵树的的深度为2,把所有边权记录下来,从大到小排序。设边权为 ,答案即为 的最小值,时间复杂度
3、 的情况(树的直径)
解法:取一条最长链,即为树的直径问题,记录一下最大值和次大值,每次把最大 值传到它的父亲,时间复杂度
以上的情况全部考虑到的话就可以获得55分及以上了,那么这是找规律和暴力做的情况。
然后是第4种情况
4、分支不超过3 (最多是二叉树)
这种情况下对于某个长度要求 只有两种情况,对于任意一个点的两个儿子有以下情况
也就是说
要么 的某个儿子节点能够形成的最长路已经满足需求长度了,那么这条路就可以自成一条路,答案+1。
要么这个点的两个儿子节点能够形成的最长路都不满足需求长度,但是如果把两个儿子节点的路通过节点
从这里我们可以发现一个问题,对于分支不超过3的节点是这样的,那么如果超过3呢?
显然我们依旧可以用 的儿子节点中任意两个点 满足 拼出满足条件的路。
那么要拼出更多的路,显然就是贪心了。
只要尽量去拼出刚好满足条件的路就可以了。也就是对于任意一条边,选择另一条长度最小,但能够和这条边拼出满足条件的路,即对于点x,选择
(当然对于本身儿子节点的路径已经满足要求的点不需要拼接其他的路,即)
那么现在只剩下一个问题,那就是如何考虑对 的父亲 来说 的最长路。
这里我们可以发现,首先能够满足条件的边一定已经被选走,跟之后的操作已经无关了。
那么对于 的儿子节点里,剩下的就只有本身最长路径不满足k,并且还不能跟其他的兄弟路径拼出满足条件的路。
可以发现这些边,虽然通过并不能拼出满足条件的路,但是更往上,到他们祖先节点,就有可能满足条件了。
但是我们也可以发现,因为所有需要到达连向儿子节点的路,都需要经过,但是一条边只能使用一次,所以 连向儿子的路中,只能选择一条使用,加上从而形成对于 来说 的最长路。
那么就是代码的事情了,我们二分修建的条路中最短的长度,然后用上面的方法check能否生成m条或以上的路满足长度≥k。这里为了方便组合两条边,我们可以使用multiset,时间复杂度
当然这里存在一个小问题,第8组数据,当时,如果二分的边界用极大值 的话就会超时,因为每次check的复杂度都是,而二分次数是log(500000000) 所以会超时。
如果没有注意到这一点,嫌麻烦直接写了个极大值边界,就只能95分