QBLT国庆集训补题清单
请自行 Ctrl+F5 查找。
P1074 [NOIP2009 提高组] 靶形数独
考虑优化搜索顺序。
如果直接搜,理论复杂度为 \(9^{67}\),显然会 \(\textbf{TLE}\)。
增加剪枝,提前判断数独合法性,仍然会寄。
这个时候我们就需要优化搜索顺序了。
回想一下,平时做数独,显然是要优先填可能性少的格子。那么这里我们选择行为关键字,优先选择 \(0\) 的数量少的格子填充即可。
实际上加上上面这个剪枝就能过了,但是这里再讲一下判合法性的优化:考虑状压,对于每一行、列、宫使用一个九位二进制数表示当前状态。第 \(i\) 位是 \(1\) 表示数字 \(i\) 已经被占,否则没有。考虑到二进制数最低位是第 \(0\) 位,那么我们把数值集体减一即可。
P1312 [NOIP2011 提高组] Mayan 游戏
此题唯一难点在于模拟。
对于方块的状态,可以分成几部分处理:
-
交换:直接
swap
。 -
掉落:对于每一列从下往上扫,遇到空格就删去。
-
消除:先消除所有符合条件的方块,然后判断是否会掉落。大力递归即可。
然后是剪枝。
-
可行性:如果某种方块数 \(<3\),就没必要搜了。
-
最优性:按照坐标从小到大去枚举。注意答案要求优先级最高,而右移的优先级大于左移,所以优先右移。
用掉上面的剪枝就过了。
代码不会写/kk
P5682 [CSP-J2019 江西] 次大值
无解情况:所有 \(a_i\) 都相等,那么此时余数都为 \(0\)。
我们首先将 \(a\) 数组排序去重。记去重后的数组长度为 \(m\)。
此时的最大值显然是 \(a_{m-1}\)。
那么次大值有哪些可能?
首先肯定有 \(a_{m-2}\)。因此答案中的 \(a_x \mod a_y\) 中的 \(x\) 不可能 \(<m-2\),\(y\) 不可能 \(\le m-2\)。
考虑如下 hack
数据:
3
1 3 5
不难发现,答案也可能是 \(a_{m-1}\mod a_m\)。
将两种情况取个 \(\max\) 即可。
P3951 [NOIP2017 提高组] 小凯的疑惑
打个表,发现规律极其显然:就是 \(a\times b-(a+b)\)。
代码就不写了。
P5662 [CSP-J2019] 纪念品
设 \(w_{i,j}\) 表示第 \(i\) 个物品第 \(j\) 天的价格(实际上就是题目里的 \(P_{j,i}\))。
我们发现,并不需要持有任何一个物品超过一天:假设在第 \(i\) 天买,\(i+2\) 天卖,那么这就等价于在第 \(i\) 天买,\(i+1\) 天卖,然后再在当天重新买回来,最后在第 \(i+2\) 天卖掉。那么我们只需要计算当天赚的钱就行了。
由于一个物品可以买卖无限次,因此这实际上是一个完全背包模型:
-
背包的容量是前 \(i-1\) 天的答案,即第 \(i\) 天拥有的金币数量。
-
物品 \(k\) 的重量是 \(w_{k,i}\)。
-
物品 \(k\) 的价值是 \(w_{k,i+1}-w_{k,i}\)。
因此只需要跑 \(T-1\) 轮背包即可求出答案。
时间复杂度:\(O(TnW)\),可以通过此题。其中 \(W\) 是金币的数量,题面中规定 \(W\le10^4\)。
P1158 [NOIP2010 普及组] 导弹拦截
先将所有导弹按照和第一个探测器的距离排序。
设第一个探测器的工作半径为 \(r\),那么答案就是所有距离第一个探测器的距离 \(>r\) 的导弹中,距离第二个探测器最远的那个导弹到第二个探测器的距离加上所有到探测器一的距离\(<r\) 的导弹和探测器一的最大距离。
那么我们滚一个后缀 \(\max\),当中记录导弹到探测器二的最远距离。
最后我们枚举第一个探测器覆盖的前缀,更新答案即可。
ABC267D - Index × A(Not Continuous ver.)
设 \(dp_{i,j}\) 为前 \(i\) 个数,选出 \(j\) 个数的答案。
边界条件:\(dp_{0,1}=-\infty\)。
转移:\(dp_{i,j}=\max(dp_{i-1,j},dp_{i-1,j-1}+a_i\times j)\)。
注意当 \(i<j\) 时不合法,此时 \(dp_{i,j}=-\infty\)。
最终答案为 \(dp_{n,m}\)。
然后就做完了。
CF1728D Letter Picking
CF1637D Yet Another Minimization Problem
CF1528A Parsa's Humongous Tree
CF1517D Explorer Space
P1541 [NOIP2010 提高组] 乌龟棋
记 \(cnt_i\) 表示卡牌 \(i\) 的张数。
设 \(dp_{p,i,j,k,l}\) 表示当前在 \(p\) 位置,使用了 \(i\) 张卡牌 \(1\),\(j\) 张卡牌 \(2\),\(k\) 张卡牌 \(3\),\(l\) 张卡牌 \(4\) 的分数。
初始条件:\(dp_{1,0,0,0,0}=a_1\),因为一开始可以自动得到起点的分数。
有转移:
判一下下标是否会变成负数即可。
但是这样空间爆了,怎么办呢?
容易发现是可以通过状态求出当前位置的,即 \(nowpos=1+i+2j+3k+4l\)。\(+1\) 是因为起点是 \(1\)。
于是我们就成功的减掉了 \(p\) 这一维。
转移:
这个……填表法或者刷表法应该都可以。这里用填表法。
若 \(i\) 不为零,则 \(dp_{i,j,k,l}=\max(dp_{i,j,k,l},dp_{i-1,j,k,l}+a_{nowpos})\)。其余三种卡牌同理。
注意数据范围,不要像我一样看错了。。。