2021.10.5 pm模拟赛题解

A 小奇采药 herb

题面描述

山洞里有一些不同的草药,小奇采每一株都需要一些时间,每一株也有它自身的价值。在一段时间里,小奇可以采到一些草药,如何让采到的草药的总价值最大。

输入格式

第1行包括1个整数 T ,表示数据组数。

对于每组数据,第1行包括2个整数 n,m ,表示草药的数目和能用于采药的时间。

接下来n行,每行两个整数 ti,vi 。保证 m,ti,vi 在限制范围内均匀随机生成。

输出格式

输出 T 行,每行1个数字,表示每组数据答案。

样例输入

1
2
3
4
5
1
3 70
71 100
69 1
1 2

样例输出

1
3

数据范围

  • 对于 30% 的数据, 1n20,1m,ti,vi104 ;
  • 对于 60% 的数据, 1n100,1m,ti,vi105 ;
  • 对于 100% 的数据, 1T10,1n150,1m,ti,vi109

思路分析

这道题的题面描述就是一道01背包的模板题,很容易想到套用模板并且把空间压缩到 Θ(m) ,时间复杂度 Θ(nm) ,但是看到后 40% 的数据范围, 1m,ti,vi109m 太大了,空间和时间都会炸掉,所以考虑与 m 无关的算法。

由于 n150 , 可以想到深搜,毕竟剪枝剪得好,搜索少不了,但是150还是有点大,需要进行可行性剪枝和最优化剪枝,其中最优化剪枝需要先行排序。由于题目说了随机生成,所以剪枝被卡的概率微乎其微。

AC代码


B 小奇取石子 stone

题面描述

小奇最近在研究取石子游戏。

n 堆石子,第 i 堆石子有 ai 颗,最多取 m 堆石子(保证 mn )。

请问在要求总石子数不超过 k 颗的情况下最多能取多少石子。

输入格式

第一行输入三个数字 n,m,k ,意义见上。 第二行 n 个数字,依次表示 ai

输出格式

输出一个数字,表示最多能取石子的个数。

样例输入

1
2
4 3 5
1 1 2 3

样例输出

1
5

数据范围

  • 对于其中 30% 的数据,1mn10,1k1000,1ai100 ;
  • 对于其中 30% 的数据, 1mn20,1k108,1ai106 ;
  • 对于另 40% 的数据, 1mn200,1k2500,1ai50

思路分析

把拿一堆石子看做两个代价:拿了一堆和拿了 ai 个。由于题目说了最多取 m 堆石子,总石子数不超过 k 颗,这道题就可以转化成一个多维限制的01背包,空间复杂度 Θ(mk) ,时间复杂度 Θ(nmk) 。但是这套卷子好像特别喜欢卡常又给了一个特别大的 k ,所以跟第一题一样,考虑深搜。

但是很容易就发现由于存在多维限制,剪枝难以进行(反正本蒟蒻想不出来),再次观察题面,发现 k 非常大的时候 n 非常小,所以可以把 k>2500 的情况进行深搜,把 k2500 的情况进行dp,时间复杂度 Θ(nmk)Θ(2n)

AC代码


C 小奇的旅行计划 plan

题面描述

小奇所在的国家一共由 n 个城市和 m 条连接这些城市的双向道路组成。

小奇非常喜欢骑自行车,它常常骑着自行车从一个城市,沿着某些双向道路到达另一个城市。 (真闲得慌)

现在,这个国家要关闭其所有的道路以便翻修 (国王出来挨打) ,但为了保证必要的交通运输,第 i 条道路会在第 i 天暂时开放。小奇为了了解本次翻修对它旅行的影响,因此想知道,如果它第 L 天在一个城市 S ,在第 R 天或之前是否能到达城市T。(小奇不需要第 L 天就立即离开,也不需要恰好在第 R 天到达城市。)

为了更全面地评估这个影响,小奇会有多次询问,但它一下子算不过来,就只好找你帮忙了。

输入格式

第一行三个正整数 n,m,q ,分别表示城市数、道路数、询问数。

接下来有 m 行,其中第 i 行有两个正整数 ui,vi(uivi) ,表示有一条连接 ui,vi 两座城市的双向道路,并且这条道路在第 i 天暂时开放,不保证整张图连通,不保证有且仅有一条道路连接 ui,vi 两座城市。

接下来 q 行,每行四个正整数 Li,Ri,Si,Ti ,表示一次询问。

输出格式

输出 q 行,第 i 行表示第 i 次询问的答案,可行输出Yes,不可行输出No

样例输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
6 10 10
1 2
1 3
2 4
3 5
3 6
4 5
3 6
2 6
5 6
1 4
1 2 3 4
1 2 3 5
1 3 4 6
1 1 1 2
1 4 5 6
1 4 1 2
1 6 1 6
1 8 1 5
3 7 4 5
5 8 2 4

样例输出

1
2
3
4
5
6
7
8
9
10
No
No
No
Yes
No
Yes
Yes
Yes
Yes
No

数据范围

  • 对于 30% 的数据, 2m,q2000
  • 对于 100% 的数据, 2n1000,1m,q2×105,1LiRim,1Si,Tin,SiTi

思路分析

很明显,这个题如果在线处理,每次查询只能限制在 O(n) 以内,但是无论怎么设计算法都得与 m 相关,所以考虑 O(nm) 的离线算法。

我们先把所有数据都读进来,对于所有询问,根据 l 从大到小排序,然后从 m 到 1 枚举每一条边,看看这一条边能够使得哪些点相连,则这两个点之间通行的开始时间就是枚举到的边的序号,然后用一个 date 数组储存两个点之间通行的结束时间。再枚举所有开始时间为边序号的查询,如果这两点通行的结束时间比要求的结束时间短,那么输出Yes,否则输出No

AC代码

D 小奇探险 explore

题面描述

小奇去遗迹探险,遗迹里有 n 个宝箱,有的装满了珠宝,有的装着废品。

小奇有地图,所以它知道每一个宝箱的价值,但是它不喜欢走回头路,所以要按顺序拿这 n 个宝箱中的若干个。拿宝箱很累的。一开始小奇的体力是 1 ,每得到一个宝箱之后,小奇得到的价值是体力 × 宝箱的价值 ,之后它的体力就会变为原来的 k(0<k<1)

小奇不喜欢连续放过很多宝箱,所以任意一段长度为 m 的序列中,小奇一定要取走其中的一个宝箱。现在小奇想知道它能得到的最大价值和。

输入格式

第一行,两个整数 n,m ,表示的含义如题目中所述。

第二行,一个小数 k ,表示的含义如题目中所述,最多4位小数。

第三行, n 个整数,第 i 个整数 vi 表示第 i 个宝箱的价值。

输出格式

第一行,两个整数 n,m ,表示的含义如题目中所述。

第二行,一个小数 k ,表示的含义如题目中所述,最多4位小数。

第三行, n 个整数,第 i 个整数 vi 表示第 i 个宝箱的价值。

样例输入

1
2
3
3 2
0.1
1 2 3

样例输出

1
2.30

数据范围

  • 对于30%的数据, 1n10
  • 对于60%的数据, 1n1000
  • 对于100%的数据, 1n100000,1mn,0<k<1,109vi109

思路分析

很容易想到定义状态 f(i) 表示前 i 个宝箱的最大价值,但是取走前面的会对后面的宝箱产生影响,不满足无后效性的要求,所以考虑用 f(i) 表示后 i 个宝箱的最大价值。由于每 m 个宝箱至少取走一个,那么 f(i)=max(f(i+1),...,f(i+m))k+v(i) ,这样就有了状态转移方程,然后考虑优化,因为 Θ(nm) 是绝对过不了的。在求最大值的过程中,我们可以用单调队列进行维护,相当于在一个长度为 m 的滑动窗口中求出最大值,这样时间复杂度就是 Θ(n)

AC代码