BZOJ1183 Croatian2008 Umnozak


Description

定义一个数的digit-product是它的各个位上的数字的乘积,定义一个数的self-product是它本身乘以它的digit-pr
oduct。编程求self-product在a和b之间的数的个数。

Input

两个整数a,b(1 ≤ a ≤ b < 10^18)。

Output

一个整数,self-product在a和b之间的数的个数。

Sample Input

145 192

Sample Output

4


数位DP,我么发现digit-product包含的质因子最多只有2,3,5,7,digit-product严格小于原数,所以digit-product不会超过1e9,所以我们可以对这个数进行枚举,只有很少的可能取值

然后我们确定了digit-product之后就可以确定原数的上下界,然后利用digit-product中,2,3,5,7的质因子个数来进行DP,注意一下边界问题什么的

。。。

反正我照标程调的


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL l,r,ans=0;
LL dp[18][30][19][13][11];
LL f[4]={2,3,5,7};
LL k[4]={0,0,0,0};
LL cnt[10][4]={
{0,0,0,0},
{0,0,0,0},
{1,0,0,0},
{0,1,0,0},
{2,0,0,0},
{0,0,1,0},
{1,1,0,0},
{0,0,0,1},
{3,0,0,0},
{0,2,0,0}
};
LL dfs(LL len,LL a,LL pot,LL l_line,LL r_line){
LL b=a+pot-1;
if(a>r_line||b<l_line)return 0;
if(len==18)return (!k[0])&&(!k[1])&&(!k[2])&&(!k[3]);
bool mem=(a>=l_line&&b<=r_line);
if(mem&&dp[len][k[0]][k[1]][k[2]][k[3]]>=0)
return dp[len][k[0]][k[1]][k[2]][k[3]];
pot/=10;
LL res=0;
for(LL i=(a!=0);i<=9;++i){
LL t=1;
for(LL j=0;j<4;j++)if(cnt[i][j]>k[j])t=0;
if(!t)continue;
for(LL j=0;j<4;j++)k[j]-=cnt[i][j];
res+=dfs(len+1,a+i*pot,pot,l_line,r_line);
for(LL j=0;j<4;j++)k[j]+=cnt[i][j];
}
if(mem)dp[len][k[0]][k[1]][k[2]][k[3]]=res;
return res;
}
LL getL(LL a,LL b){return (a+b-1)/b;}
LL getR(LL a,LL b){return a/b;}
void getans(LL up,LL prod,LL tip){
if(prod>(LL)1e9||prod*prod>up)return;
if(tip==4){
ans+=dfs(0,0,(LL)1e18,getL(l,prod),getR(r,prod));
return;
}
getans(up,prod,tip+1);
++k[tip];
getans(up,prod*f[tip],tip);
--k[tip];
}
int main(){
cin>>l>>r;
memset(dp,-1,sizeof(dp));
getans(r,1,0);
printf("%lld\n",ans);
return 0;
}

标程:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib> using namespace std; typedef long long llint; llint memo[18][30][19][13][11]; int f[4] = { 2, 3, 5, 7 };
int k[4] = { 0, 0, 0, 0 };
int code[10][4] = {
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 2, 0, 0, 0 },
{ 0, 0, 1, 0 },
{ 1, 1, 0, 0 },
{ 0, 0, 0, 1 },
{ 3, 0, 0, 0 },
{ 0, 2, 0, 0 }
}; llint rec( int digits, llint a, llint pot, llint lo, llint hi ) {
llint b = a + pot-1;
if( a > hi || b < lo ) return 0;
if( digits == 18 ) return !k[0] && !k[1] && !k[2] && !k[3]; int memoize = 0;
if( a >= lo && b <= hi ) memoize = 1; if( memoize && memo[digits][k[0]][k[1]][k[2]][k[3]] >= 0 )
return memo[digits][k[0]][k[1]][k[2]][k[3]]; pot /= 10; llint ret = 0; for( int digit = (a!=0); digit <= 9; ++digit ) { int ok = 1;
for( int i = 0; i < 4; ++i ) ok &= code[digit][i] <= k[i];
if( !ok ) continue; for( int i = 0; i < 4; ++i ) k[i] -= code[digit][i];
ret += rec( digits+1, a + digit*pot, pot, lo, hi );
for( int i = 0; i < 4; ++i ) k[i] += code[digit][i];
} if( memoize ) memo[digits][k[0]][k[1]][k[2]][k[3]] = ret; return ret;
} llint lo, hi;
llint rjesenje; llint ceil( llint a, llint b ) { return (a+b-1)/b; }
llint floor( llint a, llint b ) { return a/b; } void gen( llint limit, llint product, int factor ) {
if( product > 1000000000 || product*product > limit ) return;
if( factor == 4 ) {
rjesenje += rec( 0, 0, 1000000000000000000LL, ceil(lo,product), floor(hi,product) );
return;
} gen( limit, product, factor + 1 );
++k[factor];
gen( limit, product*f[factor], factor );
--k[factor];
} int main( void ) {
scanf( "%lld%lld", &lo, &hi ); memset( memo, -1, sizeof memo ); gen( hi, 1, 0 ); printf( "%lld\n", rjesenje ); return 0;
}

BZOJ1183 Croatian2008 Umnozak 【数位DP】*的更多相关文章

  1. 数位DP复习小结

    转载请注明原文地址http://www.cnblogs.com/LadyLex/p/8490222.html 之前学数位dp的时候底子没打扎实 虚的要死 这次正好有时间……刷了刷之前没做的题目 感觉自 ...

  2. 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP

    [BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...

  3. bzoj1026数位dp

    基础的数位dp 但是ce了一发,(abs难道不是cmath里的吗?改成bits/stdc++.h就过了) #include <bits/stdc++.h> using namespace ...

  4. uva12063数位dp

    辣鸡军训毁我青春!!! 因为在军训,导致很长时间都只能看书yy题目,而不能溜到机房鏼题 于是在猫大的帮助下我发现这道习题是数位dp 然后想起之前讲dp的时候一直在补作业所以没怎么写,然后就试了试 果然 ...

  5. HDU2089 不要62[数位DP]

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  6. 数位DP GYM 100827 E Hill Number

    题目链接 题意:判断小于n的数字中,数位从高到低成上升再下降的趋势的数字的个数 分析:简单的数位DP,保存前一位的数字,注意临界点的处理,都是套路. #include <bits/stdc++. ...

  7. 数位dp总结

    由简单到稍微难点. 从网上搜了10到数位dp的题目,有几道还是很难想到的,前几道基本都是模板题,供入门用. 点开即可看题解. hdu3555 Bomb hdu3652 B-number hdu2089 ...

  8. 数位DP入门

    HDU 2089 不要62 DESC: 问l, r范围内的没有4和相邻62的数有多少个. #include <stdio.h> #include <string.h> #inc ...

  9. 数位DP之奥义

    恩是的没错数位DP的奥义就是一个简练的dfs模板 int dfs(int position, int condition, bool boundary) { ) return (condition ? ...

随机推荐

  1. python2.7.10 VS2015编译方法

    打开 Python-2.7.10\PCbuild目录 然后设置只编译python和pythoncore: 好了,编译试一试. 出现了好几个错误.由于 VS2015 取消了 timezone 的定义,改 ...

  2. 模仿某旅行网站 纯css实现背景放大效果

    基本功能是鼠标移动到图片上,对应宽度变宽.其中布局和基本样式直接copy官网,功能部分是自己瞎鼓捣实现的. 直接上代码: HTML部分 <div class="fold_wrap&qu ...

  3. Decode Ways,编码方式数量求解。动态规划问题。

    问题描述: A message containing letters from A-Z is being encoded to numbers using the following mapping: ...

  4. python PIL/Pillow图像扩展、复制、粘贴处理

    http://blog.csdn.net/yuanyangsdo/article/details/60957685

  5. 使用VMware出现的各种问题

    ifconfig命令无效 解决办法:yum install net-tools ping不通 cd /etc/sysconfig/network-scripts ls查看所有文件名称,找到ifcfg- ...

  6. word2016_添加标题和目录

    标题 开始->标题(层级可选) 目录 引用->目录->自动目录

  7. jquery extend源码解析

    $.extend(obj1,0bj2,{"name":"s","age":22}) //target 要拷贝到哪个对象上 // i 要执行拷 ...

  8. Spring整合hibernate:3、使用XML进行声明式的事务管理

    配置applicationContext.xml文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 2 ...

  9. 在一个机器上获取大量PublicKey后的私钥恢复方法

    渗透测试过程中,有时候会在某个未授权访问漏洞中获取authorized_keys文件,里面有大量账户用于免密登录的PublicKey,这个时候如何进行下一步渗透? 可以考虑rsa碰撞的方式,找到公用p ...

  10. MPAndroidChart Wiki(译文)~Part 2

    7. 填充数据 这一章节将讲解给各式各样的图表设置数据的方法. 7.1 LineChart(线形图) 想给图表添加数据,使用如下方法: public void setData(ChartData da ...