Codeforces 55d-----状压dp and math
Posted pandaking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 55d-----状压dp and math相关的知识,希望对你有一定的参考价值。
先贴一下题目链接: https://vjudge.net/problem/CodeForces-55D
题意大致如下: 给t次询问, 每次询问给出一段区间【l,r】 要你求出这段区间中的beautiful number
漂亮数定义如下: 一个数如果为漂亮数 是它可以 被它的非零数位 整除!
然后贴一下别人的题解::::::::::::https://blog.csdn.net/Rain722/article/details/54709913
首先可以确认一点 1: 如果一个数可以被多个数整除, ((那么最重要的一点是先找出这个数的lcm))!
2:可以得出1到9这9个数的lcm是2520 (暴力算一下就可以)
3:显然在数位上的操作一般都是数位dp
4:可以确定一点, <<pos(也就是数位肯定是第一维状态)>>,那怎么唯一确定它的状态了 我们想既然找整除的数那么最终是找 余数/lcm==0,那么状态就可以划分成 数位,,,余数,,,,lcm,,,,,,, 然后余数的范围可以限制到2520,lcm由于限制它只有50个数:::::::::
那么就可以推出了!
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int mod=2520; 5 int t; 6 LL l,r; 7 LL dp[25][50][2550]; // 数位 lcm 余数 8 int Hash[2550]; //把lcm hash出来 9 int bit[25]; 10 11 LL gcd(LL a,LL b){ 12 if(b==0) return a; 13 else return gcd(b,a%b); 14 } 15 16 void init(){ 17 int cnt=0; 18 for(int i=1;i<=mod;i++) 19 if(mod%i==0) 20 Hash[i]=cnt++; 21 } 22 23 LL dfs(int pos,int have,int lcm,int lim){ 24 if(pos<=0) return have%lcm==0; 25 if(!lim&&dp[pos][Hash[lcm]][have]!=-1) return dp[pos][Hash[lcm]][have]; 26 int num=lim?bit[pos]:9; 27 LL ans=0; 28 for(int i=0;i<=num;i++){ 29 ans+=dfs(pos-1,(have*10+i)%mod,i==0?lcm:lcm*i/gcd(lcm,i),lim&&i==num); 30 } 31 if(!lim) dp[pos][Hash[lcm]][have]=ans; 32 return ans; 33 } 34 LL solve(LL m){ 35 int len=0; 36 while(m){ 37 bit[++len]=m%10;m/=10; 38 } 39 return dfs(len,0,1,1); 40 } 41 42 int main(){ 43 init(); 44 scanf("%d",&t); 45 memset(dp,-1,sizeof(dp)); //dp数组初始化 46 while(t--){ 47 scanf("%lld%lld",&l,&r); 48 printf("%lld ",solve(r)-solve(l-1)); 49 } 50 return 0; 51 }
一个不错的链接:::::https://www.cnblogs.com/vongang/p/3141273.html
以上是关于Codeforces 55d-----状压dp and math的主要内容,如果未能解决你的问题,请参考以下文章
状压dp找寻环的个数 Codeforces Beta Round #11 D
CodeForces 327E Axis Walking(状压DP+卡常技巧)
CodeForces 385 D.Bear and Floodlight 状压DP
Codeforces 55 D. Beautiful numbers