# CF 55D 数位DP

### D. Beautiful numbers

time limit per test 4 seconds

memory limit per test 256 megabytes

Description
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 numbers in given ranges.

Input
The first line of the input contains the number of cases t (1 ≤ t ≤ 10). Each of the next t lines contains two natural numbers li and ri (1 ≤ li ≤ ri ≤ 9 ·1018).

Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cin (also you may use %I64d).

Output
Output should contain t numbers — answers to the queries, one number per line — quantities of beautiful numbers in given intervals (from li to ri, inclusively).

Sample Input
Input
1
1 9
Output
9
Input
1
12 15
Output
2

### 思路：

dp[i][j][k]表示处理到第i位，这个数（包含第i位）对2520取余是j，所有位的lcm是k的数的个数。如果j对k取余等于0，则这些数是美丽数字。

k的范围是1~2520，这样会超内存，所以伴有离散化过程，所有情况的数位lcm也就48个。

``````#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
const int mod=2520; //1~9的lcm为2520
int gcd(int a,int b) {
if(b==0) return a;
return gcd(b,a%b);
}
int lcm(int a,int b) {
if(a==0) return b;
if(b==0) return a;
return a*b/gcd(a,b);
}
int index[2525];
int initIndex() {
int tmp = 0;
for(int i=1;i<=2520;i++)
if(2520%i==0) index[i] = tmp++;
}
long long dp[25][mod][50];
int bit[25];
long long dfs(int pos,int prenum,int prelcm,bool flag) { //flag为true的话表示当前位触顶了
if(pos==-1) return prenum%prelcm == 0;
if(!flag && dp[pos][prenum][index[prelcm]]!=-1) return dp[pos][prenum][index[prelcm]];
int e = flag?bit[pos]:9;
long long ans=0;
for(int i=0;i<=e;i++) {
ans += dfs(pos-1,(prenum*10+i)%mod,lcm(prelcm,i),flag&&i==e);
}
if(!flag) return dp[pos][prenum][index[prelcm]]=ans;
return ans;
}

long long solve(long long n) {
int pos=0;
while(n) {
bit[pos++] = n%10;
n/=10;
}
return dfs(pos-1,0,1,true);
}
int main() {
int T;
long long l,r;
initIndex();
memset(dp,-1,sizeof(dp));
cin>>T;
while(T--) {
cin>>l>>r;
cout<<solve(r)-solve(l-1)<<endl;
}
}
``````

• 本文已收录于以下专栏：

## 【cf】55d beautiful numbers【精妙的数位dp+离散化】

• a709743744
• 2016年07月05日 09:58
• 243

## CF 55D beautiful number（数位dp）

#include #include #include #include using namespace std; typedef long long ll; const int mod=2520; i...
• fanbaobao829
• 2017年05月24日 16:43
• 94

## CF 55D 数位dp

D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input stan...
• u012358934
• 2014年02月08日 02:46
• 1257

## cf55d

• luyuncheng
• 2013年03月24日 16:20
• 716

## CF 55D 数位DP

• reborn_ZhMZ
• 2016年06月07日 14:06
• 228

## CodeForces 55D Beautiful numbers(数位dp)

CodeForces 55D题目求给定区间内的能被自己的每一非零位整除的数的个数思路http://www.cnblogs.com/algorithms/archive/2012/09/02/26680...
• pibaixinghei
• 2016年08月13日 20:39
• 221

## 数位dp cf 55d

http://www.cnblogs.com/vongang/p/3141273.html 把数位dp写成记忆化搜索的形式，方法很赞，代码量少了很多。 下面为转载内容： 　　 a p...
• rgtjf
• 2013年09月18日 22:07
• 400

## 数位DP学习 数位DP板子理解 CF55D解题报告

【题意】先理解一下数位DP的模板，下面解释的非常清楚了。 // pos = 当前处理的位置(一般从高位到低位) // pre = 上一个位的数字(更高的那一位) // ...
• just_sort
• 2016年08月10日 11:28
• 689

## cf55D(数位DP+离散化+各种优化)

• qkoqhh
• 2018年01月31日 16:13
• 13

## CF 55D(数位DP)

• cbcbcbz
• 2017年07月14日 10:57
• 62

举报原因： 您举报文章：CF 55D 数位DP 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)