题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6796
题目大意:给你一个区间[l,r],让你求出这个区间内满足数位中众数为d的数的个数。
题解:一道披着数位dp皮的组合计数题。
如果用常规数位dp的思路去维护,不难发现状态很难维护,因此我们要考虑换一种思路。
考虑数位dp枚举当前位时,当前位不是数位的上限的情况。
eg:假设数位上限为123456789,当前枚举到第七位,之前的数位为123455(即123455XXX),
即前面数位有1个1,1个2,1个3,1个4,2个5,后面数任意取能组成众数为d的情况。
这个可以通过指数型生成函数(用来求可重集的排列方案数)求出来,具体细节参考代码。
具体的解决方法:
假设当前枚举数位为pos(即后面还有pos位可以填)
先枚举d在pos中的出现个数,至少大于之前数位中除d之外的最大出现次数(mx+1)减去之前d出现的次数,至多是pos(位数限制)。
这样d在pos中的个数就确定了,问题就转换成了已知总个数为pos,0的出现次数为[L,R]....d的出现次数为[m,m]...9的出现次数为[L,R],求从中选pos个的排列数,这是一个比较经典的可重集的排列问题,可以用指数型母函数解决。
注意i(!=d)的出现次数最少为0,最大应该为min(pos-m,m+cnt[d]-cnt[i]-1)。
因为要保证位数的限制,以及d是众数的条件(即总个数m+cnt[d]应该大于之前i出现的次数cnt[i])。