FZU2179(数位dp)

传送门:Chriswho

题意:求区间[1,n]内能整除自己本身各位数字的数的个数。

分析:这题跟CF 55D Beautiful numbers一样的,一个数能被它的所有非零数位整除,则能被它们的最小公倍数整除,而1到9的最小公倍数为2520,为了判断这个数能否被它的所有数位整除,我们还需要这个数的值,但这里我们只需记录它对2520的模即可,dp[pos][sum][lcm]表示非限制条件下(limit==0),当前在第pos位模2520余sum且前面各位数字的最小公倍数为lcm的符合条件的数的总数。

 

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 100000000
#define inf 0x3f3f3f3f
#define eps 1e-6
#define N 1010
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define PII pair<int,int>
using namespace std;
LL dp[20][2525][50];
int dig[20],num[2525];
LL times=0;
int gcd(int a,int b)
{
    return a%b==0?b:gcd(b,a%b);
}
LL dfs(int pos,int sum,int lcm,int limit)
{
    if(!pos){//times++;
            return sum%lcm==0;}
    if(!limit&&~dp[pos][sum][num[lcm]])return dp[pos][sum][num[lcm]];
    int len=limit?dig[pos]:9;
    LL ans=0;
    for(int i=0;i<=len;i++)
    {
        int newlcm;
        if(i==0)newlcm=lcm;
        else newlcm=lcm/gcd(i,lcm)*i;
        ans+=dfs(pos-1,(sum*10+i)%2520,newlcm,limit&&len==i);
    }
    if(!limit)dp[pos][sum][num[lcm]]=ans;
    return ans;
}
LL solve(LL x)
{
    int len=0;
    while(x)
    {
        dig[++len]=x%10;
        x/=10;
    }
    return dfs(len,0,1,1);
}
int check(LL n)
{
    LL x=n,flag=1;
    while(x)
    {
        int s=x%10;
        x/=10;
        if(s==0)continue;
        if(n%s)flag=0;
    }
    return flag;
}
LL fact(LL x)
{
    LL res=0;
    for(int i=1;i<=x;i++)
    {
        if(check(i))res++;
    }
    return res;
}
void init()
{
    FILL(dp,-1);
    int cnt=0;
    for(int i=1;i<=2520;i++)
        if(2520%i==0)num[i]=++cnt;
}
int main()
{
    LL n;
    int T;
    init();
    scanf("%d",&T);
    while(T--)
    {
        scanf("%I64d",&n);
        printf("%I64d\n",solve(n)-1);
      //  printf("%I64d\n",fact(b)-fact(a-1));
       // printf("%I64d\n",times);
    }
}
View Code

 

posted on 2015-02-12 18:11  lienus  阅读(160)  评论(0编辑  收藏  举报

导航