给定n,m,k(0<=n<=1e15,0<=m<=1e12,1<=k<=18),
求长度为k的数组a,ai为[0,m]的整数,
满足
答案对1e9+7取模
第一反应想起了hdu3693,但比对了一下,感觉那个题难很多,
两年前写的题忘了写题解,现在不会了
Educational Codeforces Round 104 (Rated for Div. 2) F.Ones(数位dp)_Code92007的博客-CSDN博客
后来想了想,感觉更像这个题,按余数统计方案数,
控制余数在一定范围,姑且称它为数位背包吧
每一位的贡献可以独立考虑,而这个式子实际是(i,j)对的01值不同就会产生贡献,
所以只用关注当前几个填1几个填0,由于有的卡上界有的不卡,所以记录一下当前有几个卡上界
dp[i][j][l]表示当前从高到低考虑到低i位时,只考虑n的i位及更高位时的数的当前余数是j,选的l个数卡上界的方案数
k=18时,最大贡献是9*9=81,考虑当前n的余数x最大能是多少,
(x-81)*2 所以转移过程中可以忽略>162的转移,因为通过更低的位,再也不能使其归0 而<0的转移也不可取, 因为这个操作,转移到下一位,相当于*2,下一位n有余数,相当于+1, 还有减去当前选的值,相当于减去一个非负数,而(-1)*2+1还为-1,最终不能变为0 所以,可以只关注[0,162)的转移,代码中写的是[0,256) 此外,初始局面时,n的余数超过256也显然无解 转移分两种情况讨论,当前位为0 或者 当前位为1 1. 当前位为0,卡上界的只能选0,for枚举不卡上界的数中选了x个1 2. 当前位为1,for枚举卡上界的数中选了x个1,for枚举不卡上界的数中选了y个1 选出这些数来,从而确定了贡献数对的数量,也确定了下一次卡上界的数的个数, 并算出下一位的n的当前余数,递归到子状态搜索即可 复杂度O(40*256*18*18*18),但跑不满 注意特判k=1(取不出两个数)和m=0(a数组为空)的情况代码
新编译原理的草稿
Java笔记:手写spring之ioc
钟汉良日记:你相信神话吗?你会背《正气歌》吗
RHEL - 订阅、注册系统和 Yum Repository
【LeetCode 每日一题】53. 最大子数组和
【Rancher】Rancher 2.6.x 搭建Kubernetes集群
【web前端特效源码】使用HTML5& CSS&Js实现倒计时数字
IM即时通讯开发iOS多设备字体适配方案
Vinco Ventures任命Ted Farnsworth为联合首席执行官