CodeForces 55D "Beautiful numbers"(数位DP+离散化处理)

传送门

 

参考资料:

  [1]:CodeForces 55D Beautiful numbers(数位dp&&离散化)

 

我的理解:

  起初,我先定义一个三维数组 dp[ i ][ j ][ k ]:来到 i 位置时,所有非零数的lcm = j,当前数位 k 时含有的 Beautiful numbers 的个数。

  但是,由题意得,当前的数 k 可以是个很大的数(9e18),数组根本就开不下,那怎么办呢?

  将当前的数 hash 一下,如何hash呢?

  假设 a,b,c,d 为[0,9]的数,那么不存在另一个 a',b',c',d'

  使得 a*11+b*13+c*17+d*19 = a' *11+b' *13+c' *17+d' *19;

  也就是说,这 19 位数分别乘以大于10 的互不相等的前19个素数是不会存在重数的;

  那么,hash完后,最大的数才7000多,那么开个 dp[20][50][8000] 的数组绰绰有余;

  但问题来了,既然每个数的 hash 值都不想等,那,哪来的记忆化搜索?

  所以说,这就是赤裸裸的暴力!!!!!!

  so,举足无措,只好参考大佬博客辽。

  下面具体说说我的理解:

  首先解释一下上述博客中给出的公式 sum%(x*n)%x == sum%x 的证法以及作用;

  证明:

    sum%(x*n) = sum-(int)(sum / (x*n) )*(x*n);

    sum%(x*n)%x =  [sum-(int)(sum / (x*n) )*(x*n) ] % x = sum%x - 0 = sum % x;

  那,接下来就要看看要怎么用这个公式了,预处理出 1~9的所有不同组合的 lcm ,我是用DFS预处理的;

参考代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 #define mem(a,b) memset(a,b,sizeof(a))
 7 
 8 int a[48];
 9 bool vis[10];//vis[i]:判断数字 i 是否访问过
10 bool vis2[2*3*4*5*6*7*8*9];//vis2[lcm]:判断当前的lcm是否在之前出现过
11 
12 int GCD(int a,int b)
13 {
14     return a==0 ? b:GCD(b%a,a);
15 }
16 int LCM(int a,int b)
17 {
18     return a*b/GCD(a,b);
19 }
20 
21 void DFS(int t,int lcm,int &k)
22 {
23     if(!vis2[lcm])
24     {
25         a[k++]=lcm;
26         vis2[lcm]=true;
27     }
28 
29     for(int i=1;i <= 9;++i)
30     {
31         if(vis[i])
32             continue;
33         vis[i]=true;
34         DFS(t+1,LCM(lcm,i),k);
35         vis[i]=false;
36     }
37 }
38 int main()
39 {
40     int k=0;
41 
42     mem(vis,false);
43     mem(vis2,false);
44 
45     DFS(1,1,k);
46     sort(a,a+48);
47     for(int i=0;i < k;++i)
48         printf("%d,",a[i]);
49 
50     return 0;
51 }
预处理出所有的lcm

  与处理完后,你会发现最大的lcm为2520,且 2520%(其余的lcm) = 0;

  那么,这就好办了,对于当前所形成的数 curNum 和当前的 lcm,我们需要判断 curNum % lcm 是否等于0,那么问题就是

  curNum 太大了怎么办?

  通过上面的公式,可知 curNum%lcm = curNum%(lcm*(2520/lcm) )%lcm = (curNum%2520)%lcm;

  所以,每次只需要将 curNum%2520 即可。  

posted @ 2019-03-26 09:50 hyacinthLJP 阅读(...) 评论(...) 编辑 收藏