zoukankan      html  css  js  c++  java
  • CF 55D Beautiful numbers 数位DP

    思路:

    要找一个数能被他的所有反的数字整除,只需求出这个数能被其数字的LCM整除。而LCM最大为5*7*8*9=2520;

    如果直接开dp[20][2520][2520]会超内存,而2^3,3^2,5,7的组合只有4*3*2*2=48种,所以开dp[20][2520][50]即可。

    链接:http://codeforces.com/problemset/problem/55/D

    代码如下:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define ll __int64
     5 using namespace std;
     6 int bit[20],hash[2529];
     7 ll dp[20][2521][50];
     8 int gcd(int a,int b)
     9 {
    10     if(a<b) swap(a,b);
    11     while(b){
    12         int t=a;
    13         a=b;
    14         b=t%b;
    15     }
    16     return a;
    17 }
    18 ll dfs(int pos,int num,int lcm,bool f)
    19 {
    20     if(pos==-1) return num%lcm==0;
    21     if(!f&&dp[pos][num][hash[lcm]]!=-1) return dp[pos][num][hash[lcm]];
    22     ll ans=0;
    23     int e=f?bit[pos]:9;
    24     for(int i=0;i<=e;i++){
    25         int g=lcm;
    26         if(i>=2) g=g/gcd(g,i)*i;
    27         ans+=dfs(pos-1,(num*10+i)%2520,g,f&&(i==bit[pos]));
    28     }
    29     if(!f) dp[pos][num][hash[lcm]]=ans;
    30     return ans;
    31 }
    32 ll cal(ll n)
    33 {
    34     int m=0;
    35     while(n){
    36         bit[m++]=n%10;
    37         n/=10;
    38     }
    39     return dfs(m-1,0,1,1);
    40 }
    41 int main()
    42 {
    43     ll n,m;
    44     int t,i,j;
    45     memset(dp,-1,sizeof(dp));
    46     for(j=0,i=1;i<=2520;i++){
    47         if(2520%i==0)
    48             hash[i]=j++;
    49     }
    50     scanf("%d",&t);
    51     while(t--){
    52         scanf("%I64d%I64d",&n,&m);
    53         printf("%I64d
    ",cal(m)-cal(n-1));
    54     }
    55 }
    View Code
  • 相关阅读:
    10046 event 知多少
    10046 event 知多少
    awr相关指标解析
    父子关系展示
    secureCRT启动xmanager图形化工具
    linux单用户模式
    Tor
    windows下的unix工具集:UnxUtils
    OPENLDAP
    Windows命令行重命名文件
  • 原文地址:https://www.cnblogs.com/xin-hua/p/3304245.html
Copyright © 2011-2022 走看看