[数位dp] cf 55D Beautiful numbers
2014-09-10 17:09
260 查看
题意:求[x,y]内,能被各个非零位整数的数的个数 比如312能被3、1、2整除所以算一个。
思路:首先最小公倍数的话1~9最大的是2520,然后只要顺着到当前位前的lcm是多少dfs下去就好了。
但是显然dp[20][2520][2520]是开不下的,但是注意到,到当前位的lcm是离散的,其实只有48个。
所以需要离散化成 dp[20][2520][50] 。
然后就是注意到当前位前的lcm了,处理会比较麻烦一点。
因为0的时候要跳过,第一位之前是没有的。
我的处理方式就是遇到之前的没有把之前的那位当前是本身这位。
代码:
思路:首先最小公倍数的话1~9最大的是2520,然后只要顺着到当前位前的lcm是多少dfs下去就好了。
但是显然dp[20][2520][2520]是开不下的,但是注意到,到当前位的lcm是离散的,其实只有48个。
所以需要离散化成 dp[20][2520][50] 。
然后就是注意到当前位前的lcm了,处理会比较麻烦一点。
因为0的时候要跳过,第一位之前是没有的。
我的处理方式就是遇到之前的没有把之前的那位当前是本身这位。
代码:
#include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include"algorithm" #include"iostream" #define eps 1e-8 using namespace std; int gcd(int x,int y) { return y?gcd(y,x%y):x; } int num[22],m,lcm[100],used[2700]; //used是数对应的编号,lcm是编号对应的数是多少 __int64 dp[22][2700][50],ten[22]; __int64 dfs(int site,int mod,int lcmid,int f) { if(site==0) { if(lcmid==-1) return 0; return mod%lcm[lcmid]?0:1; } if(!f&&dp[site][mod][lcmid]!=-1) return dp[site][mod][lcmid]; int len=f?num[site]:9; __int64 ans=0; for(int i=0; i<=len; i++) { int tep; if(lcmid!=-1) tep=lcm[lcmid]; //如果不是-1 就说明出现过了 直接赋值 else { if(i==0) { ans+=dfs(site-1,(mod+i*ten[site])%2520,-1,f&&i==len); //没有出现过又是0的话 跳过 continue; //记得continue } tep=i; //不是0的话 就当做本身 if(used[tep]==-1) { used[tep]=m; lcm[m++]=tep; } } tep=i?tep/gcd(tep,i)*i:tep; //不是0的话计算,是0的话就是之前的 if(used[tep]==-1) { used[tep]=m; lcm[m++]=tep; } tep=used[tep]; ans+=dfs(site-1,(mod+i*ten[site])%2520,tep,f&&i==len); } if(!f&&lcmid!=-1) dp[site][mod][lcmid]=ans; return ans; } __int64 solve(__int64 x) { if(x==0) return 0; int cnt=0; while(x) { num[++cnt]=x%10; x/=10; } return dfs(cnt,0,-1,1); } int main() { int t; cin>>t; memset(dp,-1,sizeof(dp)); m=0; memset(lcm,0,sizeof(lcm)); memset(used,-1,sizeof(used)); ten[1]=1; for(int i=2; i<=20; i++) ten[i]=(ten[i-1]*10)%2520; while(t--) { __int64 x,y; scanf("%I64d%I64d",&x,&y); printf("%I64d\n",solve(y)-solve(x-1)); } return 0; }
相关文章推荐
- CF D. Beautiful numbers (数位dp)
- cf 401D. Roman and Numbers 数位dp,状压
- CF 55D 数位DP
- 【CF908G】New Year and Original Order 数位DP
- CF855E,状压数位DP
- cf-279D - The Minimum Number of Variables-数位dp
- CF 55D - Beautiful numbers(数位DP)
- CF 55D Beautiful numbers (数位DP)
- CF 55D Beautiful numbers(数位DP)
- cf 431D 二分+数位DP
- cf 644人 二进制 数位dp?
- CF 55D 数位dp
- CF_55D——Beautiful numbers(离散化数位DP)
- 【CF628D】Magic Numbers 数位DP
- CF 55D Beautiful numbers 数位DP
- CF 55D - Beautiful numbers(数位DP)
- CF 55D Beautiful numbers(数位DP)
- CF 55D Beautiful numbers (数位DP)
- CF 55D - Beautiful numbers(数位DP)
- CF 55D 数位dp(一个数是组成它的所有位数对应数的倍数)