【数位DP】CF55D Beautiful numbers

$dp[x][p][pp]$表示第x位,当前已有数字mod 2520(1~9数字的lcm)为p,当前各位数字的lcm为pp

观察到数组太大,考虑压缩,第三维lcm最多只有9个数字,打表发现最多只有48个状态,压掉第三维即可

打表用一个状压然后set维护(广搜也可以)即可

有一个坑点:题目里似乎没有说关于0的事情(即数字里出现0)但是有人在CF上打这个比赛的时候问了出题人,碰到0不要管即可!!!

打表代码:

 1 set<int>s;
 2 inline void Make(int x){
 3     int ans=1;
 4     for(int i=0;i<9;i++){
 5         if(((1<<i)&x)) ans=lcm(ans,i+1);
 6     }s.insert(ans);
 7 }
 8 inline void States_Maker(){
 9     int ans=1;
10     for(int i=0;i<(1<<9);i++)Make(i);
11     while(!s.empty()){
12         cout<<*s.begin()<<",";
13         s.erase(s.begin());
14     }
15 }

解题代码:

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 #define writeln(x)  write(x),puts("")
 4 #define writep(x)   write(x),putchar(‘ ‘)
 5 using namespace std;
 6 inline int read(){
 7     int ans=0,f=1;char chr=getchar();
 8     while(!isdigit(chr)){if(chr==‘-‘) f=-1;chr=getchar();}
 9     while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
10     return ans*f;
11 }void write(int x){
12     if(x<0) putchar(‘-‘),x=-x;
13     if(x>9) write(x/10);
14     putchar(x%10+‘0‘);
15 }const int M = 20,State = 50;
16 int f[M][2521][State],T,n,a[M],l,r,Pos[2521],S[State]={0,1,2,3,4,5,6,7,8,9,10,12,14,15,18,20,21,24,28,30,35,36,40,42,45,56,60,63,70,72,84,90,105,120,126,140,168,180,210,252,280,315,360,420,504,630,840,1260,2520};
17 inline int gcd(int x,int y){return __gcd(x,y);}
18 inline int lcm(int x,int y){if(x==0)return y;if(y==0)return x;return x*y/gcd(x,y);}
19 int dfs(int x,int p,int pp,bool lim){
20     if(!x)return (p%pp==0)?(1):(0);
21     if(!lim&&p!=-1&&pp!=-1&&f[x][p][Pos[pp]]!=-1)return f[x][p][Pos[pp]];
22     int ans=0,up=lim?a[x]:9;
23     for(int i=0;i<=up;i++)ans+=dfs(x-1,(p*10+i)%2520,lcm(pp,i),lim&&a[x]==i);
24     if(!lim)f[x][p][Pos[pp]]=ans;
25     return ans;
26 }
27 inline int Solve(int x){
28     int len=0;
29     while(x)a[++len]=x%10,x/=10;
30     return dfs(len,0,1,1);
31 }
32 signed main(){
33     memset(f,-1,sizeof(f));
34     for(int i=1;i<=48;i++)Pos[S[i]]=i;
35     T=read();
36     while(T--)l=read(),r=read(),writeln(Solve(r)-Solve(l-1));
37     return 0;
38 }

原文地址:https://www.cnblogs.com/zhenglw/p/11594843.html

时间: 2024-10-21 12:29:03

【数位DP】CF55D Beautiful numbers的相关文章

[暑假集训--数位dp]cf55D Beautiful numbers

Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits. We will not argue with this and just count the quantity of beautiful num

CF55D Beautiful numbers (数位dp)

题目链接 题解 一个数能被一些数整除,那么一定被这些数的\(lcm\)整除 那么我们容易想到根据\(lcm\)设状态 我们可以发现有用的\(lcm\)只有\(48\)个 那么按照一般的数位\(dp\) 设出状态:\(f_{i,j,k,0/1}\)表示前\(i\)位,\(lcm=j\),模\(lcm\)的余数是\(k\),是否达到上界 但是这样子是无法转移的(因为新添加一个数模数可能会产生变化) 那么我们把模数统一成\(2520\) 复杂度\(O(T*L*48*2500*2)\) 其中\(L\)是

[暑假集训--数位dp]LightOj1205 Palindromic Numbers

A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the same when its digits are reversed. In this problem you will be given two integers i j, you have to find the number of palindromic numbers between i and j

CF55D Beautiful numbers

题目描述 对于一个数,如果他能被任何一位上的数整除,那么他就是beautiful number,有t组询问求[l,r]的beautiful number. 1<=li?<=ri?<=9⋅1018 题解 看到没有一点思路,甚至想到上次做的数位DP想把[0,9]都开出一维,但是不仅空间过不去,而且不知道咋处理这个数没出现. 那么就去借鉴题解,lcm(???) 整除每一位就是整除出现过的数的lcm!!! [1..9]的最小公倍数2520,出现过的数的lcm一定是2520的因数,所以只用判断x%

[CF55D]Beautiful numbers(数位dp,状态压缩)

题目链接:http://codeforces.com/problemset/problem/55/D 题意:给定区间,求区间内某数的所有数位能整除这个数本身的数的个数. 起初思路:dp(l,s,sum)表示这个数到l位,并且0~9出现的状态s,和为sum的时候的数字个数.发现这个sum不好处理,因为数字越来越大无法保证这个界限.用到一个性质:一个数能被一堆数整除,当且仅当这个数能被这堆数的最小公倍数整除.换句话说,我们统计这个数对1~9的最小公倍数取模,就能判断这个sum是否可以被各位数整除了.

CF55D Beautiful numbers 数位dp

恢复魔芋本质,,改了1h+,, 题目传送门 其实这个题挺水的.也就我这种忘了%大佬的蒟蒻要调这么久. 首先,我们要找的是能被每一位整除的数.处理成1~R的答案  -  1~(l-1)的答案. 从最高位开始搜索放啥.如果已经是最后一位了,且当前数能被当前各位的最小公倍数整除,它就是一个合法的方案.那么,将长度,当前和,当前lcs,是否有限制带着搜就行了. 注意,因为每一位只有1~9,这里的不同lcs最多不到50个,预处理离散化一下即可. 还有就是本组数据结束的时候要把有限制的清空,无限制的保留(最

CodeForces 55D Beautiful numbers(数位dp&amp;&amp;离散化)

题目链接:[kuangbin带你飞]专题十五 数位DP A - Beautiful numbers 题意 ps:第一道数位dp,题真好,虽然是参考大牛方法悟过才a,但仍收获不少. 求一个区间内的Beautiful numbers有多少个.Beautiful numbers指:一个数能整除所有组成它的非0数字. 例如15可以被1和5整除,所以15是Beautiful numbers. 思路 Beautiful numbers指:一个数能整除所有组成它的非0数字. 等同于 一个数能整除 所有组成它的

POJ 3252 Round Numbers(数位dp&amp;amp;记忆化搜索)

题目链接:[kuangbin带你飞]专题十五 数位DP E - Round Numbers 题意 给定区间.求转化为二进制后当中0比1多或相等的数字的个数. 思路 将数字转化为二进制进行数位dp,由于一个二进制数的最高位必须为1.所以设置变量first记录前面位是否有1,若有1,则可随意放,否则,仅仅可放1. 同一时候.上面的推断决定了搜索时len的大小与二进制本身的长度不一定相等,所以需两个变量对1和0的个数进行记录. 用dp[a][b][c]保存长度a,b个0,c个1的数字个数.记忆化搜索.

数位dp——奏响数字数位的美妙乐章

数位dp:处理数字数位关系的一种dp方式. 一般的题目特征十分明显: 1.一般和数字本身有很大关系. 2.一般求数字在区间L,R中的一些信息 3.L,R一般很大,通常能达到long long级别. dp方式也比较有套路: 一般有三种方法: 本质上的相似之处,都是集中在处理"填数有无限制","填数无限制情况下的固定方案数","某些已经搜出来的固定方案数" 1.记忆化搜索(没用过) 是一种倒着记忆的方法. 2.递推(我基本都是这个方法) 正着递推出答