http://codeforces.com/problemset/problem/55/D

Beautiful Numbers : 这个数能整除它的全部位上非零整数。问[l,r]之间的Beautiful Numbers的个数。



若一个数能整除它的全部的非零数位。那么相当于它能整除个位数的最小公倍数。

因此记忆化搜索中的參数除了len(当前位)和up(是否达到上界),有一个prelcm表示前面的数的最小公倍数。推断这个数是否是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][2050][2050],dp[i][j][k]表示处理到i位,前面的数的最小公倍数为j。前面的数%2520为k。

但这样




明显会TLE。。

由于1~9组成的最小公倍数仅仅有48个,能够离散化,这样数组就降到了dp[20][50][2520]。











#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
//#define LL __int64
#define LL long long
#define eps 1e-12
#define PI acos(-1.0)
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 4010;
const int max_lcm = 2520; LL gcd(LL a, LL b)
{
if(b == 0)
return a;
return gcd(b,a%b);
}
LL lcm(LL a, LL b)
{
return a/gcd(a,b)*b;
}
int dig[25];
LL dp[25][50][2525];
int hash[2525]; LL dfs(int len, int prelcm, int prenum, int up)
{
if(len == 0)
{
return prenum%prelcm == 0;
}
if(!up && dp[len][hash[prelcm]][prenum] != -1)
return dp[len][hash[prelcm]][prenum];
int n = up ? dig[len] : 9;
LL res = 0;
for(int i = 0; i <= n; i++)
{
int nownum = (prenum*10+i)%max_lcm;
int nowlcm = prelcm;
if(i)
nowlcm = lcm(prelcm,i);
res += dfs(len-1,nowlcm,nownum,up&&i==n);
}
if(!up)
dp[len][hash[prelcm]][prenum] = 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()
{
int test;
LL a,b;
int cnt = 0;
for(int i = 1; i <= 2520; i++) //离散化
{
if(max_lcm % i == 0)
hash[i] = ++cnt;
} scanf("%d",&test);
memset(dp,-1,sizeof(dp));
for(int item = 1; item <= test; item++)
{
scanf("%I64d %I64d",&a,&b);
printf("%I64d\n",cal(b) - cal(a-1));
} return 0;
}



CF D. Beautiful numbers (数位dp)的更多相关文章

  1. CF 55D. Beautiful numbers(数位DP)

    题目链接 这题,没想出来,根本没想到用最小公倍数来更新,一直想状态压缩,不过余数什么的根本存不下,看的von学长的blog,比着写了写,就是模版改改,不过状态转移构造不出,怎么着,都做不出来. #in ...

  2. 2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP)

    2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP) 链接:https://ac.nowcoder.com/acm/contest/163/ ...

  3. codeforces 55D - Beautiful numbers(数位DP+离散化)

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

  4. Codeforces Beta Round #51 D. Beautiful numbers 数位dp

    D. Beautiful numbers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/55/p ...

  5. CodeForces - 55D - Beautiful numbers(数位DP,离散化)

    链接: https://vjudge.net/problem/CodeForces-55D 题意: Volodya is an odd boy and his taste is strange as ...

  6. CodeForces - 55D Beautiful numbers —— 数位DP

    题目链接:https://vjudge.net/problem/CodeForces-55D D. Beautiful numbers time limit per test 4 seconds me ...

  7. cf55D. Beautiful numbers(数位dp)

    题意 题目链接 Sol 看到这种题就不难想到是数位dp了. 一个很显然的性质是一个数若能整除所有位数上的数,则一定能整除他们的lcm. 根据这个条件我们不难看出我们只需要记录每个数对所有数的lcm(也 ...

  8. Codeforces - 55D Beautiful numbers (数位dp+数论)

    题意:求[L,R](1<=L<=R<=9e18)区间中所有能被自己数位上的非零数整除的数的个数 分析:丛数据量可以分析出是用数位dp求解,区间个数可以转化为sum(R)-sum(L- ...

  9. CF55D Beautiful numbers (数位dp)

    题目链接 题解 一个数能被一些数整除,那么一定被这些数的\(lcm\)整除 那么我们容易想到根据\(lcm\)设状态 我们可以发现有用的\(lcm\)只有\(48\)个 那么按照一般的数位\(dp\) ...

  10. codeforces 55D. Beautiful numbers 数位dp

    题目链接 一个数, 他的所有位上的数都可以被这个数整除, 求出范围内满足条件的数的个数. dp[i][j][k], i表示第i位, j表示前几位的lcm是几, k表示这个数mod2520, 2520是 ...

随机推荐

  1. Python 38 初识数据库

    数据库 1.什么是mysql,什么是数据库? 文件处理就可以将数据永久存储 问题 1.管理不方便 2.文件操作效率问题 3.一个程序不太可能仅运行在同一台电脑上 提高计算机性能的方式 1.垂直扩展  ...

  2. vs2008 启动IE浏览器 出现DW20.exe占用大量cpu 服务器iis 异常调试

    DW20.exe占用大量cpu 服务器iis运行出现异常想查一下故障原因,发现有好几个DW20.exe进程,每个占用20%左右的cpu,在任务管理器中将其终止后,它又自动运行起来了 查了一下DW20. ...

  3. C# html生成PDF遇到的问题,从iTextSharp到wkhtmltopdf

    我们的网站业务会生成一个报告,用网页展示出来,要有生成pdf并下载的功能,关键是生成pdf. 用内容一段段去拼pdf,想想就很崩溃,所以就去网上找直接把html生成pdf的方法. 网上资料大部分都是用 ...

  4. PHP操作多进程

    在以往的开发项目中,要操作进程就会使用PHP自带的pcntl拓展.但是pcntl存在着许多的不足: pcntl没有提供进程间通信的功能 pcntl不支持重定向标准输入和输出 pcntl只提供了fork ...

  5. Oracle 当输入参数允许为空时

    场景: 有一个存储过程p_test 带有多个输入参数code.name.number p_test(code IN VARCHAR2,nameIN VARCHAR2,number IN VARCHAR ...

  6. SQLServer2008 在where条件中使用CASE WHEN

    create table #temp(    id int identity(1,1),    name varchar(20),    startYear int,    startMonth in ...

  7. UML基本关系

    UML-Unified Model Language 统一建模语言,又称标准建模语言.是用来对软件密集系统进行可视化建模的一种语言.UML的定义包括UML语义和UML表示法两个元素. UML是在开发阶 ...

  8. sql的padleft

    /* SELECT dbo.fn_PadLeft('8', '0', 6) */ create function fn_PadLeft(@num nvarchar(16),@paddingChar c ...

  9. java编译器和java解释器、JVM

    作用: JVM:JVM有自己完善的硬件架构,如处理器.堆栈(Stack).寄存器等,还具有相应的指令系统(字节码就是一种指令格式).JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需要生成 ...

  10. 在C#程序中,创建、写入、读取XML文件的方法

    一.在C#程序中,创建.写入.读取XML文件的方法 1.创建和读取XML文件的方法,Values为需要写入的值 private void WriteXML(string Values) { //保存的 ...