8.26 做题笔记

\(\text{2025.8.26}\)

\(\text{A}\)

题目链接

首先,我们考虑 \(O(2^n\times n)\) 的做法。我们可以枚举每个人进入队列 \(1\) 还是队列 \(2\),影响答案的只是队列里的顺序,对于每个队列,花费时间为:

\[\max^m_{i=1}(\sum^i_{j=1}a_j)+b_j \]

我们考虑使用数学归纳法证明贪心。显然,如果我们的把一个大的 \(b_i\) 不放在第一个,\(i\) 对答案的贡献就会加上一些 \(a_i\) 导致最大值变大。所以我们要把 \(b_i\) 大的尽可能放在前面。因此,我们先将数组按照 \(b\) 排序,这样影响答案的只有每个 \(a\) 被分入第 \(1\) 队还是第 \(2\) 队,我们考虑动态规划。

朴素地,我们设计 \(dp_{i,j,k}\) 表示 \(1\sim i\) 排队好,第 \(1\) 个队列里面的 \(a_i\) 之和是 \(j\),第 \(2\) 个队列的 \(a_i\) 之和是 \(k\) 的排队用时。显然的,\(j+k\) 是一定的,所以我们转移时用到 \(k\) 时可以通过计算固定的 \(j+k\) 之和,也就是 \(1\sim i\)\(a_i\) 之和。所以我们设计 \(dp_{i,j}\) 即可,含义同上,我们考虑初始状态。显然,所有人都不在队列中排队中的初始状态是 \(dp_{0,0}\)。因此初始状态是 \(dp_{0,0}\),显然对于每个数字,有两种情况,第 \(1\) 种:选择放入第 \(1\) 个队列,则转移方程如下:

\[dp_{i,j}=\max(dp_{i-1,j-a_i},j+b_i) \]

其中,\(j+b_i\) 表示当前第 \(i\) 个人加入第 \(1\) 个队列用餐的用时,与其他人的用时取最大值即可。同理,如果把第 \(i\) 个元素我们加入第二个队列,当我们定义 \(sum_i\)\(1\sim i\)\(a_i\) 之和,转移方程如下:

\[dp_{i,j}=\max(dp_{i-1,j},sum_i-j+b_i) \]

其中,\(sum_i-j\) 就是我们省去的那一维 \(j\)\(sum_i-j+b\) 表示当前第 \(i\) 个人加入第 \(2\) 个队列用餐的用时。为了让答案最小,我们在转移时对两种可能的情况取最小值即可。我们注意到第 \(1\) 种方案只有 \(j\geq a_i\) 可能被转移,所以我们需要特殊判断,满足 \(j\geq a_i\) 才可以对两种情况取最小值,否则只能取第二种情况。最后的答案就是:

\[\min^{\sum a_i}_{i=1}dp_{n,i} \]

由于本题赛时做了加强,数据范围为 \(n\leq 500\),我们需要滚动数组,注意第二种情况转移时要先记录原来的 \(dp_j\),再用记录的值做转移,否则你得到的 \(dp_j\) 已经被第一种情况修改该过了。

时间复杂度:\(O(n\sum a_i)\)

空间复杂度:\(O(\sum a_i)\)

\(\text{B}\)

题目链接

我们一步一步思考本题。首先我们把题目转化,实际上,问题相当于每分钟把所有 \(a_i\) 减去 \(1\),最终需要所有 \(a_i>0\)。我们每次可以贪心地将所有最小的 \(a_i\) 都加上 \(1\),直到加上之后仍然有 \(a_i=1\) 即可。因此,我们得到了 \(O(n^3\log n)\) 的思路。

我们考虑只有一个 \(k\) 需要被查询的情况。我们不难发现如果第 \(x\) 天可以合法,显然第 \(x-1\) 天也合法,因此我们考虑二分 \(x\)。对于一个质量为 \(a\) 的冰,我们都需要通过 \(x-a+1\) 次操作让他合法,我们最多可以进行 \(kx\) 次操作,所以我们直接判断:

\[\sum^n_{i=1} \max(0,x-a_i+1)\leq kx \]

现在我们把复杂度优化到了 \(O(n^2\log w)\),我们考虑继续优化。当前的复杂度瓶颈在于如何求 \(\max(0,x-a_i+1)\) 之和,我们将 \(a\) 排序后首先找到一个最大的点 \(p\),满足 \(a_p\leq x\),那么算式就是 \(x-a_i+1\) 的和,显然和可以拆分为 \(p(x+1)-sum_p\),其中 \(sum_p\) 表示 \(1\sim p\)\(a_i\) 之和。这样做 \(p\) 仍然需要 \(\log n\) 的时间寻找,时间复杂度为 \(O(n\log n\log w)\)

接着我们来考虑值域 \(\leq 10^6\)。由于现在的复杂度瓶颈就在寻找 \(p\) 上面,我们不难发现我们可以预处理 \(f_i\),表示 \(i\) 的出现次数,随后预处理 \(cx_i\) 满足 \(cx_i=cx_{i-1}+f_i\),即可求出 \(1\sim i\) 的数出现个数。这样的话我们就可以使用 \(p=cx_x\),这样复杂度为 \(O(w+n\log w)\),可以拿到 \(80\) 分。

接着我们考虑特殊性质,即为 \(a_i\) 全部相等的情况。显然要么全部 \(a_i\) 都小于等于 \(x\),要么 \(a_i\) 都大于 \(x\),所以我们直接判断即可,这样复杂度为 \(O(n\log w)\),可以拿到 \(90\) 分。

最后我们来思考正解。显然的,\(p\) 只会在 \(x=a_i\) 时相较于 \(x-1\) 发生变化,而 \(x=a_i\) 时的 \(p\) 是可以预处理的。所以我们不难发现,我们可以先在 \(a\) 中二分出一个大致的范围 \([a_i,a_{i+1}-1]\),使得 \(i\) 最大,这里的 \(p\),我们可以使用值域的方法进行预处理,哈希表即可。接着我们确定一下范围,其中 \(p\) 全部相等,我们就不需要计算这个 \(p\),直接使用即可。通过这种拆开做二分的做法,我们可以把复杂度优化到 \(O(n\log w)\),注意到 \(\text{STL}\) 的哈希表有一定常数,我们手写哈希可以优化掉 \(3\sim 4\) 倍的常数。但是显然,直接计算 \(xn\) 对于 \(n\geq 10^{12}\) 会出现整数溢出,但是此时的 \(p\) 一定是 \(n\),所以我们直接解决不等式:

\[n(x+1)-y\leq xk \]

此处的 \(x\) 可以解不等式为:

\[x\leq \frac{y-n}{n-k} \]

我们直接特殊判断即可。本题具有一定的教育意义,是一个有趣的题目。

posted @ 2025-08-27 15:07  lzn_tops  阅读(5)  评论(0)    收藏  举报