AGC061 C. First Come First Serve
题目链接:https://atcoder.jp/contests/agc061/tasks/agc061_c
做法
显然的方向:我们可以让一些选择非法,使得每个答案对应一个合法的选择。
准确来说,我们定义 $ff[i]$ 表示最大的 $j$ 使得 $i<k\le j$ 满足 $l_k<r_i$ 。
我们考虑每个顾客,填 $1$ 表示选择离开时候记录,$0$ 表示选择进入时记录。
那么一个位置填 $0$ 的条件为 $(i,ff[i]]$ 中有一个位置填 $0$ 或者存在一个位置 $k$ 填 $1$ 且 $i\in (k,ff[k]]$ 。
然后用 DP 维护合法方案即可。
一个显然的傻瓜式 DP 是:
$f_1[i]$ 表示 $i$ 填 $1$ 的目前合法序列个数。
$f_2[i]$ 表示 $i$ 填 $0$ 的可能合法序列个数。
$f_3[i]$ 表示 $i$ 填 $0$ ,$i-1$ 填 $1$ 的合法序列个数。
转移即可。
但是这里要讲一个优化,把 $f_3$ 优化掉,就是有一个转移是:
$f_2->f_3$ ,内容为往后放若干 $1$ 后放一个 $0$ ,那我们不妨先转移到 $f_1$ ,再减去没有放 $0$ 的序列(即减去不合法的序列)
于是:
$f_1[j]+=f2i),f_1[j]-=(j\in (i+1,ff[i]])$
但是这时又产生了一个疑惑,在化简了式子后可以缩减为:
$f_1[i+1]+=f_2[i],f_1[ff[i]]-=f_2[i]$ 。
其实不难发现,所有的不合法方案在 DP 过程中都一定会经过 $f_1[ff[i]]$ 且贡献为 $1$ ,减掉即可。
时间复杂度:$O(n)$ 。
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Oldplace!
评论