CF 55D Beautiful numbers 数位DP
2013-09-05 20:38
465 查看
思路:
要找一个数能被他的所有反的数字整除,只需求出这个数能被其数字的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
代码如下:
View Code
要找一个数能被他的所有反的数字整除,只需求出这个数能被其数字的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
代码如下:
#include<cstdio> #include<cstring> #include<algorithm> #define ll __int64 using namespace std; int bit[20],hash[2529]; ll dp[20][2521][50]; int gcd(int a,int b) { if(a<b) swap(a,b); while(b){ int t=a; a=b; b=t%b; } return a; } ll dfs(int pos,int num,int lcm,bool f) { if(pos==-1) return num%lcm==0; if(!f&&dp[pos][num][hash[lcm]]!=-1) return dp[pos][num][hash[lcm]]; ll ans=0; int e=f?bit[pos]:9; for(int i=0;i<=e;i++){ int g=lcm; if(i>=2) g=g/gcd(g,i)*i; ans+=dfs(pos-1,(num*10+i)%2520,g,f&&(i==bit[pos])); } if(!f) dp[pos][num][hash[lcm]]=ans; return ans; } ll cal(ll n) { int m=0; while(n){ bit[m++]=n%10; n/=10; } return dfs(m-1,0,1,1); } int main() { ll n,m; int t,i,j; memset(dp,-1,sizeof(dp)); for(j=0,i=1;i<=2520;i++){ if(2520%i==0) hash[i]=j++; } scanf("%d",&t); while(t--){ scanf("%I64d%I64d",&n,&m); printf("%I64d\n",cal(m)-cal(n-1)); } }
View Code
相关文章推荐
- CF 55D Beautiful numbers (数位DP)
- 【CF908G】New Year and Original Order 数位DP
- CF855E,状压数位DP
- cf-279D - The Minimum Number of Variables-数位dp
- cf 644人 二进制 数位dp?
- CF 55D - Beautiful numbers(数位DP)
- cf 431D 二分+数位DP
- CF 55D 数位DP
- CF 55D Beautiful numbers(数位DP)
- CF 55D 数位dp
- CF 55D - Beautiful numbers(数位DP)
- 【CF628D】Magic Numbers 数位DP
- CF 55D Beautiful numbers (数位DP)
- CF 55D 数位dp(一个数是组成它的所有位数对应数的倍数)
- CF_55D——Beautiful numbers(离散化数位DP)
- CF 55D. Beautiful numbers(数位DP)
- CF-55D-数位DP-Beautiful Number
- CF 55D Beautiful numbers(数位DP)
- CF 55D - Beautiful numbers(数位DP)
- CF 55D beautiful number(数位dp)