zoukankan      html  css  js  c++  java
  • 51nod 1232 完美数

    题目思路:数位dp,若这个数能被每位的非0数整除,那么这个数一定可以被每一位数的lcm整除,lcm(1,2,3,4,5,6,7,8,9) = 2520,所以可以通过将这个数对2520取模来压缩空间,取模结果计做mod

    dp[pos][lcm][mod],显然20*2520*2520仍然过大,所以我们对mod进行离散,再次压缩空间。

    #include <iostream>
    #include <cmath>
    #include <string.h>
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    using namespace std;
    #define LL long long
    #define MAXSIZE 2600
    #define INF 0x3f3f3f3f
    
    LL dp[20][50][MAXSIZE];
    const LL Mod = 2520;
    
    int bit[MAXSIZE],ha[MAXSIZE];
    
    LL gcd(LL n,LL m)
    {
        if(n%m == 0)
            return m;
        return gcd(m,n%m);
    }
    
    void Init()
    {
        int pos = 1;
        for(int i=1;i<=Mod;i++)
        {
            if(2520%i == 0)
                ha[i] = pos++;
        }
    }
    
    LL dfs(int pos,int lcm,int mod,int limit)
    {
        if(pos < 0)
        {
            if(mod%lcm == 0)
                return 1;
            return 0;
        }
    
        if(dp[pos][ha[lcm]][mod] != -1 && !limit)
            return dp[pos][ha[lcm]][mod];
    
        LL ans = 0;
        int len = limit?bit[pos]:9;
        for(int i=0;i<=len;i++)
        {
            if(i != 0)
            {
                int new_lcm = lcm*i/(gcd(lcm,i));
                int num = (mod*10+i)%Mod;
                ans += dfs(pos-1,new_lcm,num,limit&&i==len);
            }
    
            else
            {
                int num = mod*10%Mod;
                ans += dfs(pos-1,lcm,num,limit&&i==len);
            }
        }
        if(!limit)
            dp[pos][ha[lcm]][mod] = ans;
        return ans;
    }
    
    LL Solve(LL n)
    {
        int pos = 0;
        while(n)
        {
            bit[pos++] = n%10;
            n /= 10;
        }
        LL ans = dfs(pos-1,1,0,1);
        return ans;
    }
    
    int main()
    {
        Init();
        int T;
        LL n,m;
        scanf("%d",&T);
        memset(dp,-1,sizeof(dp));
        while(T--)
        {
            scanf("%lld%lld",&n,&m);
            LL ans = Solve(m) - Solve(n-1);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Python—模块
    Python之路_Day5
    Python之路_Day4
    Py获取本机指定网卡的ip地址
    Python之路_Day3
    Python之路—Day2作业
    Python之路—Day2
    Python之路—Day1作业
    Python之路—Day1
    Python数据类型
  • 原文地址:https://www.cnblogs.com/alan-W/p/7800174.html
Copyright © 2011-2022 走看看