【BZOJ3679】数字之积

Description

一个数x各个数位上的数之积记为f(x) <不含前导零>
求[L,R)中满足0<f(x)<=n的数的个数

Input

第一行一个数n
第二行两个数L、R

Output

一个数,即满足条件的数的个数

Sample Input

5
19 22

Sample Output

1

HINT

100%     0<L<R<10^18 , n<=10^9

题解:真心喜欢这种搜索+DP的题~

先预处理出f(x)所有可能的取值,然后设dp[i][j]表示有i位,f值为j的数的个数。

但是f(x)的值可能很多,不过f(x)的质因子只有2,3,5,7,所以DFS即可,最后合法的f值不会超过6000个。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map> using namespace std;
typedef long long ll;
map<ll,int> mp;
ll n,l,r;
int m;
ll now;
ll pri[]={2,3,5,7},val[6000],f[20][12][6000];
ll v[20];
void dfs(int dep)
{
if(now>n) return ;
if(dep==4)
{
mp[now]=++m,val[m]=now;
return ;
}
int t=0;
dfs(dep+1);
while(now*pri[dep]<=n) now*=pri[dep],t++,dfs(dep+1);
while(t--) now/=pri[dep];
}
ll calc(ll x)
{
if(!x) return 0;
ll ret=0;
int i,j,k,mx=0;
ll tmp=1;
while(x) v[++mx]=x%10,x/=10;
for(i=1;i<mx;i++) for(j=1;j<=9;j++) for(k=1;k<=m;k++) ret+=f[i][j][k];
for(i=mx;i;i--)
{
for(j=1;j<v[i];j++)
for(k=1;k<=m;k++) if(tmp*val[k]<=n) ret+=f[i][j][k];
tmp*=v[i];
if(!tmp||tmp>n) break;
}
if(!i) ret++;
return ret;
}
int main()
{
scanf("%lld%lld%lld",&n,&l,&r);
int i,j,k,h;
now=1,dfs(0);
for(i=1;i<=9;i++) f[1][i][mp[i]]=1;
for(i=2;i<=18;i++)
for(k=1;k<=9;k++)
for(j=1;j<=m;j++) if(f[i-1][k][j])
for(h=1;h<=9;h++) if(val[j]*h<=n)
f[i][h][mp[val[j]*h]]+=f[i-1][k][j];
printf("%lld",calc(r-1)-calc(l-1));
return 0;
}//1000 1 100

【BZOJ3679】数字之积 DFS+DP的更多相关文章

  1. BZOJ3679: 数字之积(数位dp)

    题意 题目链接 Sol 推什么结论啊. 直接大力dp,$f[i][j]$表示第$i$位,乘积为$j$,第二维直接开map 能赢! /* */ #include<iostream> #inc ...

  2. BZOJ3679 : 数字之积

    设f[i][p2][p3][p5][p7][j][k]表示前i位,2,3,5,7的次数,前i位是否等于x,是否有数字的方案数 然后数位DP即可,ans=cal(r)-cal(l) #include&l ...

  3. BZOJ 3679 数字之积 数位DP

    思路:数位DP 提交:\(2\)次 错因:进行下一层\(dfs\)时的状态转移出错 题解: 还是记忆化搜索就行,但是要用\(map\)记忆化. 见代码 #include<cstdio> # ...

  4. dfs+dp思想的结合------hdu1078

    首先是题目的意思: 从一个正方形的0,0点开始走,只能横着走,竖着走,最多走k步,下一个点的数一定要比当前这个点的值大,每走一步,就加上下一个点的数据,问数据最大能有多少. 首先遇到这种题目,走来走去 ...

  5. BZOJ_1833_[ZJOI2010]count 数字计数_数位DP

    BZOJ_1833_[ZJOI2010]count 数字计数_数位DP 题意: 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 分析: 数位DP f[i][ ...

  6. HDU1978How Many Ways 记忆化dfs+dp

    /*记忆化dfs+dp dp[i][j]代表达到这个点的所有路的条数,那么所有到达终点的路的总数就是这dp[1][1]加上所有他所能到达的点的 所有路的总数 */ #include<stdio. ...

  7. 记忆化搜索(DFS+DP) URAL 1223 Chernobyl’ Eagle on a Roof

    题目传送门 /* 记忆化搜索(DFS+DP):dp[x][y] 表示x个蛋,在y楼扔后所需要的实验次数 ans = min (ans, max (dp[x][y-i], dp[x-1][i-1]) + ...

  8. 记忆化搜索(DFS+DP) URAL 1501 Sense of Beauty

    题目传送门 /* 题意:给了两堆牌,每次从首部取出一张牌,按颜色分配到两个新堆,分配过程两新堆的总数差不大于1 记忆化搜索(DFS+DP):我们思考如果我们将连续的两个操作看成一个集体操作,那么这个操 ...

  9. 【cf1111】C. Creative Snap (dfs+dp)

    传送门 简单的dfs+dp即可解决.根本不用动态开点 /* * Author: heyuhhh * Created Time: 2019/11/13 10:12:42 */ #include < ...

随机推荐

  1. VSCode打开大文件插件

    hexdump for vscode 其实没什么插件,上面的是十六进制文件的插件,对于大文件还是建议用专业的ST或者Notepad++这些.

  2. UIView和UIImageView 旋转消除锯齿方法

    方法一: calendarImageView_ =[[UIImageView alloc] initWithFrame:CGRectMake(3,3,60,72)];     calendarImag ...

  3. Android JNI&NDK编程小结及建议

    前言 由于网上关于JNI/NDK相关的知识点介绍的比较零散而且不具备参照性,所以写了这篇JNI/NDK笔记,便于作为随时查阅的工具类型的文章,本文主要的介绍了在平时项目中常用的命令.JNI数据类型.签 ...

  4. python 类和__class__理解

    __class__可理解为对象所属的父类 class A: def __init__(self,url): self.url = url def out(self): return self.url ...

  5. MFC中 报错:error : bitmap file Res\tankBattle.ico is not in 3.00 format

    今天换了一个ico图标,本来源图像是bmp的,让我改了后缀名成ico. 然后编译就报错了:error : bitmap file Res\tankBattle.ico is not in 3.00 f ...

  6. Linux中ping不通外网

    在linux中ping www.baidu.com 无法ping通 需要修改vi /etc/resolv.conf 增加如下内容: nameserver 114.114.114.114 nameser ...

  7. 【性能优化】——前端性能优化之DOM

    前言:本文参考学习自 RenChao Guan的博客,来源FSUX.ME,感谢原作者,本文的思维导图为自己整理 补充: 浏览器工作流程 避免重绘和回流的四种方式的具体实现

  8. sqlite constraint

    sqlite3中的约束例如以下: CREATE TABLE CheckTable (rowId integer primary key autoincrement, name text not nul ...

  9. Solidworks如何保存为网页可以浏览的3D格式

    1 如图所示3D装配图,在Solidworks中可以旋转,缩放.   2 我想要另存为在浏览器中可以缩放,旋转的格式.如下所示(我的装配图初步.htm)   3 步骤是,先在Solidworks中出版 ...

  10. es6 - 模板

    'use strict'; // es5 let name = 'mrs'; let qb = 20; function logs() { return 'goods!'; } let html = ...