ABC419E题解
有点耻辱,打比赛的时候去吃饭了,最后赛后 20 分钟就把 E 题写出来了……还给我掉了分╥﹏╥…又被 ABC 做局了。
题目大意
给定长为 $N$ 的整数序列,每次操作可以将单个元素加一,求至少多少次操作,使得每个长为 $L$ 的子段和为 $M$ 的倍数。
题目分析
让每个固定长度的子段和为一个数的倍数……这一眼就很数学,或者说很有规律啊。我们发现,如果有
$$\sum_{i=k}^{k+L-1}a_i\equiv \sum_{i=k+1}^{k+L}a_i\equiv0\pmod{M}$$
那恒等式两边减去公共部分 $\sum_{i=k+1}^{k+L-1}a_i$,就有
$$a_k\equiv a_{k+L}\pmod{M}$$
那我们就可以把每隔 $L$ 个的数分为一类,每类的数字对 $M$ 取模相同。那这样,我们只需要把前 $L$ 项的数算出,就可以用把剩下的都算出来了。
只用算前 $L$ 项,观察到 $L\leq N,M\leq500$,我们可以枚举每一项和前一项模 $M$ 的余数,就可使用动态规划进行状态转移(一眼 dp)。
令 $dp_{i,j}$ 表示使前 $i$ 项的和对 $M$ 取模为 $j$ 的最小操作数,$sum_{i,j}$ 表示把和 $i$ 同类的数对 $M$ 的余数都改为 $j$ 的最小操作数( $sum$ 可以直接枚举算),那么转移式如下
$$ dp_{i, (j+k) mod \ M}= \min (dp_{i-1,k}+sum_{i,j}) $$
其中 $k$ 表示前一项模 $M$ 的余数,$(j+k) mod \ M$ 表示这一项模 $M$ 的余数。
代码
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Muyang的博客!
评论










