#51 D. Beautiful numbers (数位dp+离散化)
来源:互联网 发布:网络开展学生教育工作 编辑:程序博客网 时间:2024/06/05 11:05
题目链接:
点击打开链接
http://codeforces.com/contest/55/problem/D
题意:
定义:Beautiful Numbers : 这个数能整除它的所有位上非零整数。问你[ l , r ] 之间的Beautiful Numbers的个数。
题解:
数位dp。
如果一个数能整除它的所有的非零数位,那么相当于它能整除个位数的最小公倍数。因此记忆化搜索中的参数除了len(当前位)和flag(是否达到上界),有一个pre_lcm表示前面的数的最小公倍数,判断这个数是否是Beautiful Numbers,还要有一个参数表示前面数,但是这个数太大,需要缩小它的范围。
解决方法:
缩小前面组成的数的范围。
可以发现所有个位数的最小公倍数是2520,假设当前的Beautiful Numbers是x,
那么 x % lcm{ dig[ i ] } = 0,
又 2520%lcm{ dig[ i ] } = 0。
那么x%2520%lcm{ dig[i] } = 0,x范围由9*10^18变为2520。
经过分析后可以设出dp[20][2520][2520],dp[ i ] [ j ][ k ]表示处理到i位,前面的数的最小公倍数为j,前面的数%2520为k。这样做居然会TLE...明显爆内存...
因为1~9组成的最小公倍数只有48个,1 ,2, 3, 4, 5, 6, 7, 8 ,9 ,10 ,12 ,14 ,15 ,18, 20, 21 ,24, 28, 30 ,35, 36, 40 ,42, 45, 56, 60, 63, 70 ,72 ,84 ,90 ,105 ,120, 126, 140 ,168 ,180 ,210, 252, 280, 315 ,360, 420, 504 ,630 ,840, 1260 ,2520。一共48个。 可以离散化,这样数组就降到了dp[20][50][2520]。
AC代码:
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int max_lcm=2520;int dig[25];int Hash[2525];ll dp[25][50][2525];ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}ll lcm(ll a,ll b){return a/gcd(a,b)*b;}ll dfs(int len,int pre_lcm,int pre_num,int flag){if(len==0){return pre_num % pre_lcm ==0;}if(!flag && dp[len][ Hash[pre_lcm] ][pre_num]!= -1 )return dp[len][ Hash[pre_lcm] ][pre_num];int n = flag ? dig[len] : 9;ll res = 0;for(int i=0;i<=n;i++){int now_num = (pre_num * 10 +i) % max_lcm;int now_lcm = pre_lcm;if(i) now_lcm = lcm(pre_lcm,i);res += dfs(len-1,now_lcm,now_num,flag&&i==n);}if(!flag){dp[len][Hash[pre_lcm]][pre_num] = res;}return res;}ll cal(ll num){int len=0;while(num){dig[++len]=num%10;num/=10;}return dfs(len,1,0,1);}int main() { //freopen("in.txt","r",stdin);int t;ll a,b;int cnt=0;for(int i=1;i<=2520;i++){if(max_lcm%i==0){Hash[i]=++cnt;}}cin>>t;memset(dp,-1,sizeof(dp));while(t--){scanf("%I64d %I64d",&a,&b);//cout<<cal(b)-cal(a-1)<<endl;printf("%I64d\n",cal(b)-cal(a-1));} return 0; }
- #51 D. Beautiful numbers (数位dp+离散化)
- CodeForces 55D Beautiful numbers(数位dp&&离散化)
- codeforces 55D Beautiful numbers(数位dp+离散化)【模板】
- Beautiful numbers [数位dp][离散化]
- 【数位DP+离散化】Beautiful numbers CodeForces
- CF D. Beautiful numbers (数位dp)
- Codeforces Beta Round #51 D. Beautiful numbers (数位dp)
- 【cf】55d beautiful numbers【精妙的数位dp+离散化】
- CF_55D——Beautiful numbers(离散化数位DP)
- Beautiful numbers (数位dp)
- Codeforces Beta Round #51---D. Beautiful numbers(数位dp, 巧妙)
- Codeforces Beta Round #51 D. Beautiful numbers(数位dp)
- codeforces--55D--Beautiful numbers(数位dp,dfs+记忆化)
- CF 55D - Beautiful numbers(数位DP)
- CodeForces 55D Beautiful numbers(数位dp)
- CodeForces 55D Beautiful numbers (数位DP)
- codeforces 55D Beautiful numbers(数位dp进阶)
- Codeforces 55D - Beautiful numbers(数位dp)好
- Markdown自用手册
- HaBer管理
- Qt安装MySQL数据库插件
- 小圆围绕大圆360度旋转的2种方法
- 简易随机验证码
- #51 D. Beautiful numbers (数位dp+离散化)
- nginx架构(二)Nginx服务器实现负载均衡配置
- 安装windows下的Linux工具包
- 使用pandas将numpy中的数组数据保存到csv文件
- JSP动作标识
- 苹果应用加急审核操作流程
- 七磅(SevenPounds)
- 鸟哥学习笔记14:Linux账号管理与ACL权限配置
- 模拟双色球