【BZOJ3679】数字之积 DFS+DP
【BZOJ3679】数字之积
Description
一个数x各个数位上的数之积记为f(x) <不含前导零>
求[L,R)中满足0<f(x)<=n的数的个数
Input
第一行一个数n
第二行两个数L、R
Output
一个数,即满足条件的数的个数
Sample Input
19 22
Sample Output
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的更多相关文章
- BZOJ3679: 数字之积(数位dp)
题意 题目链接 Sol 推什么结论啊. 直接大力dp,$f[i][j]$表示第$i$位,乘积为$j$,第二维直接开map 能赢! /* */ #include<iostream> #inc ...
- BZOJ3679 : 数字之积
设f[i][p2][p3][p5][p7][j][k]表示前i位,2,3,5,7的次数,前i位是否等于x,是否有数字的方案数 然后数位DP即可,ans=cal(r)-cal(l) #include&l ...
- BZOJ 3679 数字之积 数位DP
思路:数位DP 提交:\(2\)次 错因:进行下一层\(dfs\)时的状态转移出错 题解: 还是记忆化搜索就行,但是要用\(map\)记忆化. 见代码 #include<cstdio> # ...
- dfs+dp思想的结合------hdu1078
首先是题目的意思: 从一个正方形的0,0点开始走,只能横着走,竖着走,最多走k步,下一个点的数一定要比当前这个点的值大,每走一步,就加上下一个点的数据,问数据最大能有多少. 首先遇到这种题目,走来走去 ...
- BZOJ_1833_[ZJOI2010]count 数字计数_数位DP
BZOJ_1833_[ZJOI2010]count 数字计数_数位DP 题意: 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 分析: 数位DP f[i][ ...
- HDU1978How Many Ways 记忆化dfs+dp
/*记忆化dfs+dp dp[i][j]代表达到这个点的所有路的条数,那么所有到达终点的路的总数就是这dp[1][1]加上所有他所能到达的点的 所有路的总数 */ #include<stdio. ...
- 记忆化搜索(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]) + ...
- 记忆化搜索(DFS+DP) URAL 1501 Sense of Beauty
题目传送门 /* 题意:给了两堆牌,每次从首部取出一张牌,按颜色分配到两个新堆,分配过程两新堆的总数差不大于1 记忆化搜索(DFS+DP):我们思考如果我们将连续的两个操作看成一个集体操作,那么这个操 ...
- 【cf1111】C. Creative Snap (dfs+dp)
传送门 简单的dfs+dp即可解决.根本不用动态开点 /* * Author: heyuhhh * Created Time: 2019/11/13 10:12:42 */ #include < ...
随机推荐
- 洛谷 P1618 三连击(升级版)【DFS/next_permutation()/技巧性枚举/sprintf】
[链接]:https://www.luogu.org/problemnew/show/P1618 题目描述 将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数的比例是A:B:C,试 ...
- vue.js移动端app实战2
貌似有部分人要求写的更详细,这里多写一点vuel-cli基础的配置 什么是vue-cli? 官方的解释是:A simple CLI for scaffolding Vue.js projects,简单 ...
- c++ 幕客网
http://m.imooc.com/course/list.html?c=cplusplus http://coding.imooc.com/ http://www.imooc.com/act/al ...
- EasyMvc入门教程-高级控件说明(15)方位布局控件
现在很多管理后台都流行全屏切割的布局,大体结构如下图所示: 大家注意到没,整个布局是五个部分组成:“东西南北中”,EasyMvc对应的实现的代码为: @(Html.Q().Layout().TextC ...
- Flutter开发记录part3
(1) 获取当前屏幕宽度 width: MediaQuery.of(context).size.width, (1) pull_to_refresh,smartrefresh 自定义文字: new S ...
- Google SEO 学习网站记录
在搜索结果中创建良好的标题和摘要: https://support.google.com/webmasters/answer/35624?hl=zh-Hans&ref_topic=600194 ...
- 2016.7.12 错误:syntax error at or near “(”
错误提示: 错误原因:漏了个,号.
- tomcat启动项目,起不起来
右键tomcat 选择publish
- JAVA Eclipse开发Android如何让超出界面的部分自动显示滚动条
在原有布局的最外围添加一层ScrollView,注意原有布局的声明也要删了 <ScrollView xmlns:android="http://schemas.android.com/ ...
- PHP 变量定义及使用
php的变量前面必须有$符号,而且是解释型的弱类型语言,定义的时候不需要定义变量值的类型. $str="这是个变量"; 1.输出的时候可以用拼接字符串的方法 如:echo" ...