Atcoder ABC402 题解
ABC402
A
扫一遍字符串,只输出小于等于 Z 的即可。
B
建一个队列,\(1\) 操作就 push 一个元素进去,\(2\) 操作就输出队首并 pop。
C
用一个 vector 数组记录下每种食物所在的菜肴编号。
扫一遍 \(b\) 数组,每次暴力将 \(b_i\) 所在的菜肴的 \(k\) 减一,什么时候减到 \(0\) 了,什么时候这个菜肴就可以吃了。
每个菜肴里每个配料最多扫一遍。时间复杂度 \(O(n+\sum k)\)。
D
先说结论:记一条过点 \(a\) 和点 \(b\) 的直线的【斜率】\(k\) 为 \(a+b\)。两条直线 \(i, j\) 平行,等价于 \(k_i \equiv k_j \pmod n\)。
证明也很平凡,考虑两条“相邻”的直线,即,直线【平移】一个单位,就是将 \(a\) 减一,\(b\) 加一(有可能反过来,但是他们的和一定是不变的)。而将 \(1\) 减一会变成 \(n\),与 \(0\) 模 \(n\) 同余;将 \(n\) 加一同理。
结合图示,还是很明显的。
每次多加一条直线 \(i\),就是加上 \(i-1\) 条之前的,减去斜率相同的。
桶记录一下就行。
E
非常诈骗的概率期望题。
所谓的【最优策略】很恼人,不能用有效的方法直接确定。
考虑搜索。
有如下伪代码:
int ans
for(i : 1~n, c[i] <= x) {
ans := max(ans, p[i] * (s[i] + calc(x - c[i])) + (1-p[i]) * calc(x - c[i]))
}
return ans
中间计算贡献的部分,严格按照期望的定义:概率与收益相乘。
这样算出来的答案是错误的(偏小)。原因在于我们没有必要将已通过的题目再交一遍。
于是传参多记录一个状压变量,记录第 \(i\) 题是否已通过。
当然,直接搜索是过不了的,需要记忆化。
状态数 \(O(X\cdot 2^n)\),转移 \(O(n)\),粗略估计时间复杂度不高于 \(O(Xn \cdot 2^n)\),可以通过。
F
这题一看,\(2n-2 \le 38\) 的数据范围,一看就很折半。可惜这类题没做过。
我们将 \(a_{i, j}\) 为 \(a_{i, j} \times 10^{2n-i-j}\),这样路径权值就是 \(a\) 之和。
显然是从 \((1, 1)\) 走 \(n-1\) 步(此时恰好走到副对角线上),从 \((n, n)\) 走 \(n-1\) 步(也恰好走到副对角线上),再合并。
我们用两个 set 数组,记录两端(起点开始用 \(s1_i\) 记录,终点开始用 \(s2_i\) 记录)走到 \((i, n-i+1)\) 的路径权值和。
记 \(P\) 为模数。
枚举 \(s1_i\) 中的数 \(x\),我们希望不【进位】,看看对应 \(s2_i\) 中最大的小于 \(P-x\) 的数;如果不存在,就只好【进位】,拿 \(s2_i\) 中最大的数加上 \(x\),对 \(P\) 取模,更新答案。
\(s1\) 和 \(s2\) 的数字个数都是 \(2^n\) 级别的。
时间复杂度 \(O(2^n \log 2^n) = O(n \cdot 2^n)\)。
G
似乎要大力推式子以及用整除非常牛的性质,场过 \(5\) 人,显然不可做。

浙公网安备 33010602011771号