zoukankan      html  css  js  c++  java
  • CodeForces 55D Beautiful numbers

    数位dp中不错的题目

    求能够整除自身各位数字的数,那换句话来说也就是能够整除各位数的最小公倍数,可以算出1-9所有数字的最小公倍数为2000+

    从高位向下走的时候,要保留当前第几位i,当前lcm,以及前面对lcm的余数r,不过这个lcm是变换的,状态无法保存。

    可以看下这个式子 x%m = x%(2*m)%m  显然,是可以的。那么就想到有没有一个lcm是所有可能出现的lcm的倍数,可以想到就是上面算出的2000+

    现在就能确定函数里的几个参数了,i,lcm,MOD,r  但是这样存的话 明显数组开不了,又可以想下其实1-9中算出来的最小公倍数的数量不会有2000+这么多

    1 2 3 4 5 6 7 8 9  最后为 5 7 8 9 也就是 5 7 2^3 3^2  那么总共的最小公倍数数量也就为2*2*4*3 = 48 这样就可以节省内存了。

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stdlib.h>
     6 #include<vector>
     7 #include<cmath>
     8 #include<queue>
     9 #include<set>
    10 using namespace std;
    11 #define N 2520
    12 #define LL long long
    13 #define INF 0xfffffff
    14 const double eps = 1e-8;
    15 const double pi = acos(-1.0);
    16 const double inf = ~0u>>2;
    17 LL dp[22][50][N+2];
    18 int d[20],p[55],o,po[N+2];
    19 void init()
    20 {
    21     int i,g=0;
    22 
    23     for(i = 1; i <= N ; i++)
    24     if(N%i==0)
    25     po[i] = ++g;
    26 
    27 }
    28 LL dfs(int i,bool e,int lcm,int r)
    29 {
    30     if(i==-1)
    31     return r%lcm==0;
    32     if(!e&&dp[i][po[lcm]][r]!=-1)
    33     return dp[i][po[lcm]][r];
    34     int j;
    35     int mk = e?d[i]:9;
    36     LL ans = 0;
    37     for(j = 0 ;j <= mk ; j++)
    38     {
    39         if(j==0)
    40         ans+=dfs(i-1,e&&j==mk,lcm,(r*10)%N);
    41         else
    42         {
    43             int ll = lcm/__gcd(lcm,j)*j;
    44             ans+=dfs(i-1,e&&j==mk,ll,(r*10+j)%N);
    45         }
    46     }
    47     return e?ans:dp[i][po[lcm]][r] = ans;
    48 }
    49 LL cal(LL x)
    50 {
    51     int g = 0;
    52     while(x)
    53     {
    54         d[g++] = x%10;
    55         x/=10;
    56     }
    57     return dfs(g-1,1,1,0);
    58 }
    59 int main()
    60 {
    61     int t;
    62     LL l,r;
    63     cin>>t;
    64     init();
    65     memset(dp,-1,sizeof(dp));
    66     while(t--)
    67     {
    68         cin>>l>>r;
    69         cout<<cal(r)-cal(l-1)<<endl;
    70     }
    71     return 0;
    72 }
    View Code
  • 相关阅读:
    ETL高级教程学习笔记
    Silverlight for BI (step 1)对这个技术与BI可行性的初步技术分析
    再次留个纪念
    SQLServer2008BI新特性学习笔记
    Lucene.NET 2.0示例代码
    [转]ADO.NET中sqlserver和oracle的参数格式
    金山毒霸2008公测版在VISTA下发生的一个错误
    ZedGraph下Web中显示图形笔记
    信息收集的一些感悟
    个人比较看好的Silverlight 2 beta1里的东西
  • 原文地址:https://www.cnblogs.com/shangyu/p/3682966.html
Copyright © 2011-2022 走看看