A.CodeForces - 55D Beautiful numbers
题意
一个正整数是 漂亮数 ,当且仅当它能够被自身的各非零数字整除。我们不必与之争辩,只需计算给定范围中有多少个漂亮数。
思路
因为问你的是一段区间内有多少数能整除他的所有非零数位
1-9,1,一定能被任何正整数整除,1-9的最小公倍数为2520
而1-2520中真正是1-9中的最小公倍数的只有48个
dp i j k:因为dp25,2520,[2520]开不下,所以我们要进行适当离散化
index[]数组标记1-2520,哪些是真正的最小公倍数,是第几个
所以dp[i][j][k]:长度为i的数,该数对2520取模为j,它的数位和的最小公倍数是第k个->index[i]
1 |
|
B.HDU - 4352 XHXJ’s LIS
题意
问你一个longlong范围内(a,b)中每一位的数字组成的最长严格递增子序列(LIS)长度为K的个数
题意
首先 关系到数字和位数 数位DP
然后LIS 最长递增子序列利用二分查找当前递增子序列中是否有大于它的数,如果有替换最小的哪一个,如果没有就加入长度+1;可以利用状态压缩保存当前的最长递增子序列的类型;因为数字最多十个所以类型最多长度为10,用二进制的1表示当前位数的这个数在最长递增子序列中;
然后注意前导0的处理
1 |
|
C.HDU - 2089 不要62
题意
中文题
思路
数位DP模板题
1 |
|
D.HDU - 3555 Bomb
题意
求1-n中出现49的数的个数,不要62的反例
思路1
不要62的反解 注意ac(n)算的是0-n之前的数其中包括了0 因为多减去了一个0所以结果要再加上0
1 |
|
思路2
正着做 DP[第几个数]//[这个数这个位是不是4]///[这个数前面存不存在49]
1 |
|
E.POJ - 3252 Round Numbers
题意
求L到R中二进制里面0的数量大于等于1的数量的个数
思路
二进制的数位DP,但是注意这个有关前导0,如果有前导零的话遇到0就不能加上0的数量;
dp【第几位】【0的数量】【1的数量】
1 |
|
F.HDU - 3709 Balanced Number
题意
求范围内的平衡数字的个数,从数字到枢轴的距离是它与枢轴之间的偏移。然后可以计算左右部分的扭矩。如果它们是相同的,它是平衡的。平衡数字必须与其某些数字处的枢轴平衡。例如,4139是一个平衡数字,其中枢轴固定为3.对于左侧部分和右侧部分,扭矩分别为4 2 + 1 1 = 9和9 * 1 = 9。
思路
枚举枢轴的位置(1-len)然后和加起来,易知一个数最多只能有一个枢轴,假设有一个枢轴 后移动枢轴位置的,那么 平衡数字不可能会变成0.
然后再减去前导0的数比如00 000 0000
如果中间的平衡数的值小于0了那么这个数的这个位置为枢轴的肯定没有平衡数;比如前面已经4359以3为枢轴 左边是4*1 右边是5 ->4-5=-1 在过去值肯定比-1要小
1 |
|
G.HDU - 3652 B-number
题意
要13并且能被13整除的数;模板题,要标记当前余的数和前面的那个数!!和是否有13
1 |
|
H.HDU - 4734 F(x)
题意
一个A 一个B,给出一个F(x)的定义,让你求出0-B中有多少个F(x)<=F(a)
思路
一开始是想直接存每个数的F(x)然后和F(a)比较,不过这样就不能记忆化搜索了,后来发现直接存F(a)-F(x)的差值就行了如果差值小于0就直接返回 ,而且F(a)的最大值只有20736左右
1 |
|
I.ZOJ - 3494 BCD Code
题意
给定N个01串,再给定区间[a,b],问区间[a,b]里面有多少个数转化成BCD码之后不包含任何前面给出01串。1 <= A <= B <= 10^200
题解
正好最近都在做AC自动机,一看到不包括前面的01串马上想到自动机….首先把前面的N个01串扔进AC自动机里面求出坏点,表示当前当前点可以走那些数字,然后判断0-9的BCD码有没有接触到不能走的点
注意数字太大要用字符串存取
这题真有趣,真好AC自动机和数位DP的结合
1 |
|
J.HDU - 4507 吉哥系列故事――恨7不成妻
题意
求指定范围内与7不沾边的所有数的平方和。结果要mod 10^9+7
思路
与7不沾边的数需要满足三个条件。
①不出现7
②各位数和不是7的倍数
③这个数不是7的倍数
这三个条件都是基础的数位DP。
但是这题要统计的不是符合条件个数,而是平方和。
也就是说在DP时候,要重建每个数,算出平方,然后求和。
需要维护三个值(推荐使用结构体), 假定dfs推出返回的结构体是next,当前结果的结构体是ans
①符合条件数的个数 cnt
②符合条件数的和 sum
③符合添加数的平方和 sqsum
其中①是基础数位DP。②next.sum+(10^len×i)×ans.cnt,其中(10^len×i)×ans.cnt代表以len为首位的这部分数字和。
③首先重建一下这个数,(10^len×i+x),其中x是这个数的后面部分,则平方和就是(10^len×i)^2+x^2+2×10^len×i×x,其中x^2=next.sqsum
整体还要乘以next.cnt,毕竟不止一个。
这样sqsum+=next.sqsum
sqsum+=(2×10^len×i×x)×next.cnt=(2×10^len×i)×next.sum(神奇的化简)
sqsum+=(10^len×i)^2×next.cnt
mod之后统计函数也有个小陷阱,那就是f(r)在mod之后有可能小于f(l-1)。也就是要对负数取正数模。
1 |
|
K.SPOJ - BALNUM Balanced Numbers
题意
问[L, R]内有多少数字,满足每个奇数都出现了偶数次,每个偶数都出现了奇数次(没有出现的数不考虑)
题解1
用三进制来表示状态,0表示没出现,1表示出现奇数次,2表示出现偶数次。
然后就是裸的数位DP了
特别注意&&的优先度是低于==的
1 |
|
解法2
可以多出一阶存1-9是否出现过 不过数组不能开到1<<11 要开到1<<10+50左右不然会超时
1 |
|