【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 < ...
随机推荐
- 更新到xcode10以后出现几个无奈的问题,谨已此篇告诫广大ioser升级请慎重
1.第一次用xcode 10 archive的时候遇到的电脑卡死不动的问题,期间鼠标键盘通通都动不了,只能强制关机来解决,于是又进行了一次可还是遇到相同的问题,无奈之下只能等待,大约20分钟左右(20 ...
- CSU 1777: 大还是小?【模拟/后导0】
293419 roniking 1777 Accepted 2032 0 C++ 2000 2018-04-03 19:21:25 Description 输入两个实数,判断第一个数大,第二个数大还是 ...
- 分享Kali Linux 2017.1镜像
分享Kali Linux 2017.1镜像 Kali Linux官方于4月24日发布Kali Linux 2017.1版本.该版本仍然采用滚动更新方式,所以软件源为kali-rolling.至现在分 ...
- JAVA基础之Set接口
个人理解: Set接口是Collection接口的子类,其继承了所有方法,HashSet集合则实现了Set接口,其内部存储数据时依靠哈希表,一个类似数组和链表的结合体.设置空集合时,存在默认的容量和加 ...
- java 两个int类型的数据相除并输出百分号保留两位有效数字
java代码: public void IntA(int a , int b){ //首先判断分母不能为0 if(b!=0){ folat num = (float) a*100/b; Decimal ...
- 第一次用THINKPHP 报路径错
我第一次 看网上写的代码 define('THINK_PATH','ThinkPHP');define('App_NAME','43');define('App_PATH','.'); require ...
- Java中的http相关的库:httpclient/httpcore/okhttp/http-request
httpclient/httpcore是apache下面的项目:中文文档下载参考 5 官网:http://hc.apache.org/ 在线文档:http://hc.apache.org/httpco ...
- 【开发总结】—— BABYLON 3D开发常见问题及解决方法
前言:组内同事们根据长时间的Babylon.js开发实践,一起将项目开发中遇到的问题及解决方法做了一个梳理. ios [最好] 关闭离线缓存—— 解决添加了反射的mesh 丢失的问题 不要使用 pos ...
- mysqldumps 远程备份
普通模式 mysqldump -uroot -ppassword -h10.26.114.25 -P3306 --databases databasename > XXX.sql 多条在一起模式 ...
- React Native 三:样式
一.声明和使用样式 1.React Native里面的样式和使用如以下所看到的.StyleSheet.create这个构造函数不是必须的. index.android.js文件 import Reac ...