最简单数位DP 不解释
挺坑!注意有正反向两种连续,传递序列里是否有2,4这两个参数,另外还要传有没有连续,所以DFS到下一层时要写作
Is_four||i==4; Is_two||i==8;
Is_continuous||((i==pre+2&&i==last+1)||(pre==i+2&&last==i+1))
另外注意高位的0不能记录(如0000212154,要看做212154),但是不能这样枚举:for(int i=(pos==c[0]);i<=lim;i++),这样会省略掉很多情况,比如00001268,这样的数据是合法的,只是要忽略0判断。
可以直接保证当前的数大于上一个数,传一个last,然后再枚举时continue即可,这里同样要处理高位的0,同上,但是注意要把高位0换成一个小点的值,因为要比较大小。
逐位取模,没什么好说的..
要被13整除,且含有连续子串13,记is13和isone参数,每次到下一层都更新为
is13||(isone&&i==3),当然,在pos=0的时候不要忘了判定is13==1
字串含49,记isfour和is49参数,见上。
当然,上面两道题也可以先求不含13/49的,再取补集。
注意处理高位0,注意abs坑爹。
记一个sum参数表示当前各位的f(x)之和,在pos=0时与事先处理好的Limit比较,可以使用系统自带的pow函数,格式为 pow(底数,指数)。
3198 -- 【模拟试题】Amount of degrees
求能被K个B的n次幂加得,其实就是能否把这个数表示成B进制,且每位为1或0,共有K个1。
记x的B进制,因为题设中2^n系数为1,所以每位只能枚举0和1,pos=0是判断cnt(个1)是否等于K。
显然,如果当前c[pos]为0,就只能lim=0,如果c[pos]>0,只能取lim=1,因为只能枚举2种情况,但是,判定flag的时候是看的i==c[pos]而不是lim!因为lim只能是0或1,会造成漏解。
3741 -- 【USACO 2006 November silver】Round Numbers圆环数
记录两个参数分别统计二进制下0和1的个数,这里的高位0会影响统计,所以需要处理!
注意不能就记录个1或者0的个数,再拿c[0]-cnt_number来比较,会受到高位0的影响!
跟迷信的黄学长非常相似,记is_eight, is_four, is_cont来比较,一定注意手机号首尾不为0,所以枚举要为:for(int i=(pos==c[0]);i<=lim;i++)
为什么不处理高位0呢?因为00000xxxx是非法的,处理高位0反而会错,最高位从1开始,其他的0都合法。
1905 -- 【Hoj1983】Beautiful numbers
神题啊!
首先给结论 :1.a%n=a%(k*n)%n, k为正整数。
2.a%b=0,a%c=0--->a%lcm(b,c)=0.
3.lcm(1,2,3,...,9)=2520
那么,我们记录一个mod,表示当前数各个位%2520的结果,再记一个lcm,表示各个位的数字的最小公倍数。
在pos=0的时候,判断mod能否被lcm整除即可。
因为,若这个数a为美丽数,则a%lcm=a%(lcm*k)%lcm=a%2520%lcm=0,pos=0时,通过判断a%2520%lcm是否等于0来判断a%lcm是否为0,即美丽数