数位dp Beautiful numbers

原创 2016年08月30日 22:20:45

题目描述:
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

大致题意:

统计一个区间内美丽数的个数。
一个数可以整除它自己的每一位数,就称这个数为美丽数。
这个代码研究了很长时间。思路注释上了。

ac代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
#define mod 2520
ll dp[20][mod][50];
int tem[22];
int indx[mod+5];
ll gcd(ll a,ll b)
{
    return b==0?a:gcd(b,a%b);
}
ll LCM(ll a,ll b)
{
    return a/gcd(a,b)*b;
}
ll dfs(int len,int pre,int lcm,bool fp)
{
    if(!len)        //到了最后一位,如果pre%lcm==0,那么pre就是一个美丽数。
        return pre%lcm==0;   //递归出口!
    if(!fp && dp[len][pre][indx[lcm]]!=-1)  //如果当前状态没有上限,并且该状态已经遍历过。那么就直接返回。
        return dp[len][pre][indx[lcm]];
    int maxn=fp?tem[len]:9;  //有上限的话,当前位最多取到tem[len],没有上限的话就可以取到9.
    ll ans=0;
    for(int i=0;i<=maxn;i++)       //遍历len位的数。
    {
        int nowsum,nowlcm=lcm;
        nowsum=(pre*10+i)%mod;
        if(i)
            nowlcm=LCM(lcm,i);        //当前数的最小公倍数。
        ans+=dfs(len-1,nowsum,nowlcm,fp && i==maxn);
    }
    if(!fp)
        dp[len][pre][indx[lcm]]=ans;  //记忆化搜索。
    return ans;
}
void init()  //这里主要是为了压缩空间。因为符合条件的i只有48个,所以可以将dp的第3维压缩到50.
{
    int i;
    int num=0;
    for(i=1;i<=2520;i++)
    {
        if(mod%i==0)
            indx[i]=++num;
    }
    memset(dp,-1,sizeof(dp));
}
ll cal(ll a)
{
    int top=0;
    while(a)
    {
        tem[++top]=a%10;
        a=a/10;
    }
    return dfs(top,0,1,1);
}
int main()
{
    int t;
    ll a,b;
    scanf("%d",&t);
    init();
    while(t--)
    {
        scanf("%I64d%I64d",&a,&b);
        printf("%I64d\n",cal(b)-cal(a-1));
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

数位dp入门详解

基础篇 数位dp是一种计数用的dp,一般就是要统计一个区间[le,ri]内满足一些条件数的个数。所谓数位dp,字面意思就是在数位上进行dp咯。数位还算是比较好听的名字,数位的含义:一个数有个位、十位...
  • CillyB
  • CillyB
  • 2017年02月19日 23:07
  • 1769

【数位dp】(涉及到处理前导0问题)

数位dp记忆化搜索中,深搜计算dp值必先经过0-0-0 这条递归途径, 如果前导0对答案不影响那么无所谓,但是影响答案那么需要记录处理。 问题来源比较奇特,我理解错了SPOJ - BALNUM的题意...
  • qq_33199236
  • qq_33199236
  • 2017年05月24日 19:52
  • 301

数位dp总结 之 从入门到模板

for(int i=le;i
  • wust_zzwh
  • wust_zzwh
  • 2016年08月03日 14:37
  • 16278

【数位DP】BZOJ3780数字统计

Time Limit: 10 Sec Memory Limit: 128 MB Description 小A正在研究一些数字统计问题。有一天他突然看到了一个这样的问题: 将[L..R][L.....
  • cqbztsy
  • cqbztsy
  • 2016年02月26日 12:20
  • 661

数位DP学习小结

一、学习心得体会 问题描述: 一般体现为,定义某种性质K,问某区间内具有K性质的数的个数 往往给的区间会很大,对区间内的每个数进行判断显然会超时 于是数位DP登场 数位DP,顾名思义,是对数字的每一位...
  • tomorrowtodie
  • tomorrowtodie
  • 2016年08月06日 21:03
  • 1373

HDU2089 不要62(数位DP入门经典题目)

昨天做了一道很奇怪的数字题,不知道怎么做,今天才知道是数位DP ……我来学习学习。 传送门 大意:给定区间[n,m][n,m],求在n到m中没有“62“或“4“的数的个数。如62315包含62,8...
  • geng4512
  • geng4512
  • 2015年08月24日 20:48
  • 1175

[jzoj]3735. 【Usaco2014Open银组】里程计(odometer) (经典数位DP+详细分析)

https://jzoj.net/senior/#main/show/3735Problem:求[x..y][x..y]中的有趣数.有趣数的定义如下:若一个数字至少有一半以上的数位上拥有相同的数字,则...
  • Algor_pro_king_John
  • Algor_pro_king_John
  • 2017年07月30日 21:25
  • 262

【数位DP——题集及提示】

4207 -- 【模拟试题】不要62    最简单数位DP 不解释 4600 -- 【模拟试题】迷信的黄学长   挺坑!注意有正反向两种连续,传递序列里是否有2,4这两个参数,另外还要传...
  • qq_30303087
  • qq_30303087
  • 2016年04月28日 22:26
  • 457

poj3252 数位dp(所有比n小的二进制位0的个数不少于1的个数)记忆化搜索

http://poj.org/problem?id=3252 Description The cows, as you know, have no fingers or thumbs an...
  • u013573047
  • u013573047
  • 2015年02月21日 08:46
  • 878

2017广东工业大学程序设计竞赛决赛 Problem G: 等凹数字(回文+数位dp)

Problem G: 等凹数字 Description 定义一种数字称为等凹数字,即从高位到地位,每一位的数字先非递增再非递减,不能全部数字一样,且该数是一个回文数,即从左读到右与从右读到左是一样...
  • HHH_go_
  • HHH_go_
  • 2017年03月29日 18:27
  • 1062
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数位dp Beautiful numbers
举报原因:
原因补充:

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