模拟42 题解

A. 世界线

毒瘤出题人,bitset题卡空间。

于是将所有的点分成两份,做两次拓扑排序,bitset只用开一半,空间就能够了。

 

 

B. 时间机器

似乎是很显然的贪心,然而没想到。

只会打更加显然的网络流暴力。

按左端点排序,set维护一下不断取后继就行了,当没有后继即为无解。

 

 

 

C. 密码

将所有合法的组合数打个表,找一下规律。

然后整个机房的屏幕中都出现了奇怪的01三角形。

然而并没有用。

这个数据范围,正解显然是数位dp。

将组合数拆为一个阶乘除两个阶乘的形式,我们只关注p这个质因子出现的次数。

已经拆为阶乘了,就去想如何表示一个阶乘中p因子出现的个数。

这个是见过很多遍的题,就是不断除p相加。

于是我们将组合数中的n,m,n-m分别拆为p进制(这个太难想到了)。

n!中质因子p的个数其实就是

枚举考虑从最高位开始的$0$~$log_p^n-1$位,p进制表示下,这几位表示的数 的和,

注意p的指数要上下相减,所以考虑m与n-m相加的过程,

组合数$C_n^m$中p出现的次数,其实就是m与n-m,在p进制下作加法,进位的次数。

问题转化为求

两数相加不大于n,且在p进制下进位不少于k次的方案数。

于是直接数位dp(暴力记忆化搜索),

状态要设为四维,$dp(i,j,0/1,0/1)$表示从考虑最高位到第i位,进位了j次,第i位是否进位,从最高位到第i位是否受到最大值l的限制。

dp的第三维看似没有必要,但如果不考虑,真的无法写出转移。

暴力$p^2$枚举下一位的两个数填什么,可以做到80分。

如果发现了特殊的性质:枚举的过程中其实加的都是重复的东西。

将这个系数求出来,大概是公差为1的等差数列加公差为0的等差数列(其实就是简单乘积)。

复杂度变为状态数。

应当注意的是,在普通的数位dp(dfs做法)中,我们无需对状态的最后一维(是否受最大值限制)进行记忆化。

因为在通常的搜索树中,它只会被搜索一次,这个记忆化是没有意义的。

然而本题考虑的是两数加和,有/无进位两种情况,都由下一位的同一个受限制的状态转移,不记忆化会使复杂度飙到$O(n)$级别。

posted @ 2019-09-13 23:47  skyh  阅读(149)  评论(0编辑  收藏  举报