CF 55D 数位DP

原创 2016年06月07日 14:06:12

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了,记忆化搜索。已知1~9的lcm是2520。
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+离散化】

题意: 求1-n中,能被所有组成他的非0数整除的数的个数 题解: 题意很简单,但是考虑到数位dp的状态转移,dfs(pos,pre,status,limit)如果要记录除以他所有数那么势必要用数...
  • a709743744
  • 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
  • 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
  • u012358934
  • 2014年02月08日 02:46
  • 1257

cf55d

此题其实说实话不算是数位dp把,虽然我不是按最优的方法过的。但是感觉记忆划搜索是可以的 这个人写了个优化的:http://hi.baidu.com/sunhaowenprime/item/d3155...
  • luyuncheng
  • luyuncheng
  • 2013年03月24日 16:20
  • 716

CF 55D 数位DP

题目大意:一个整数如果能被它的所有非零数位整除,那么称这个数字为美丽数字。求给定区间内美丽数字的个数。...
  • reborn_ZhMZ
  • 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
  • pibaixinghei
  • 2016年08月13日 20:39
  • 221

数位dp cf 55d

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

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

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

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

这个题比较不好弄。。首先要维护搜到当前的lcm,以及处理余数问题。。 余数这个取谁的余比较好呢。。这个需要取1-9的lcm比较好,利用公倍数的性质,将余数状态强压到2520以内 然后复杂度就变...
  • qkoqhh
  • qkoqhh
  • 2018年01月31日 16:13
  • 13

CF 55D(数位DP)

嗯,写完这个题后对数位dp有了一个更清楚的认识 关键是对状态的一些理解 题意就是对l到r区间内,能被他的非零位数整除的数的个数 那么对于每一个第k位,前面数字之和是i,前面位数的最小公倍数是j的...
  • cbcbcbz
  • cbcbcbz
  • 2017年07月14日 10:57
  • 62
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CF 55D 数位DP
举报原因:
原因补充:

(最多只允许输入30个字)