BZOJ3679: 数字之积 数位DP

标签: 数位DP
9人阅读 评论(0) 收藏 举报
分类:

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


Sample Input
5
19 22


Sample Output
1


突然发现自己没写过数位DP的blog,写一篇!!!
首先我们发现直接开数组n太大会爆炸。。。
然后我们发现其实1~9的质因数是有限的:2、3、5、7
那你开一个五维数组f[i][x2][x3][x5][x7]表示到第i位,有x2个2,x3个3,x5个5,x7个7。
然后就数位DP乱搞。。。


#include <cstdio>
#include <cstring>

using namespace std;
typedef long long LL;

LL f[20][31][21][13][12];
int n, a[20], len;
int k2, k3, k5, k7;

LL dfs(int x, int x2, int x3, int x5, int x7, bool pd, bool limit) {
    LL oo = 1;
    for(int i = 1; i <= x2; i++) oo *= 2;
    for(int i = 1; i <= x3; i++) oo *= 3;
    for(int i = 1; i <= x5; i++) oo *= 5;
    for(int i = 1; i <= x7; i++) oo *= 7;
    if(oo > n) return 0;
    if(x == 0) {
        if(oo <= n && !pd) return 1;
        else return 0;
    }
    if(f[x][x2][x3][x5][x7] != -1 && !limit && !pd) return f[x][x2][x3][x5][x7];
    int up = 9; LL ans = 0; if(limit) up = a[x];
    if(pd) ans += dfs(x - 1, x2, x3, x5, x7, 1, limit);
    for(int i = 1; i <= up; i++) {
        bool uu = 0;
        if(limit == 1 && i == up) uu = 1;
        int y2 = x2, y3 = x3, y5 = x5, y7 = x7;
        if(i == 2) y2++; if(i == 3) y3++; if(i == 4) y2 += 2; if(i == 5) y5++; if(i == 6) y2++, y3++;
        if(i == 7) y7++; if(i == 8) y2 += 3; if(i == 9) y3 += 2;
        ans += dfs(x - 1, y2, y3, y5, y7, 0, uu);
    }
    if(!limit && !pd) f[x][x2][x3][x5][x7] = ans;
    return ans;
}

LL solve(LL x) {
    if(x == 0) return 0;
    len = 0;
    while(x) a[++len] = x % 10, x /= 10;
    LL ans = 0;
    memset(f, -1, sizeof(f));
    for(int i = 0; i <= a[len]; i++) {
        bool h1 = 0, h2 = 0;
        if(i == 0) h1 = 1; if(i == a[len]) h2 = 1;
        int y2 = 0, y3 = 0, y5 = 0, y7 = 0;
        if(i == 2) y2++; if(i == 3) y3++; if(i == 4) y2 += 2; if(i == 5) y5++; if(i == 6) y2++, y3++;
        if(i == 7) y7++; if(i == 8) y2 += 3; if(i == 9) y3 += 2;
        ans += dfs(len - 1, y2, y3, y5, y7, h1, h2);
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    LL x, y; scanf("%lld%lld", &x, &y);
    printf("%lld\n", solve(y - 1) - solve(x - 1));
    return 0;
}
查看评论

美化你的文字

  想玩点文字横向拉宽的特效吗?很简单,你不需要去计算什么 Width + 1 之类的象素值,只需调用一个 API 函数,就可以搞定!她就是——SetTextCharacterExtra()   这个...
  • AttaBoy
  • AttaBoy
  • 2001-05-30 19:39:00
  • 849

BZOJ 3679 数字之积 - 数位dp

题目描述分析(From Claris):考虑计算[1;R)内满足条件的数的个数。 数字之积非常大,但是这些数字的质因子只可能是2、3、5、7。 所以设f(i;cnt2;cnt3;cnt5;cnt7...
  • yuanxinyu402
  • yuanxinyu402
  • 2016-02-23 20:23:44
  • 448

【BZOJ 3679】数字之积

人生第一道数位DP,首先对于每位数的乘积,有一个很显然的转移方程 d[i][j]d[i][j]表示ii位数乘积为jj的方案数,则有 d[i][j]=∑1≤k≤9,k|jd[i−1][k/j]d[i...
  • Lcomyn
  • Lcomyn
  • 2015-07-30 16:34:58
  • 1158

【bzoj3679】 数字之积 数位dp

裸的数位dp,豪爷讲课的时候秒掉了,但是后来发现会MLE,于是我们做这么一件事,考虑数字的乘积一定是2、3、5、7的多少次幂之积,于是我们对于一个n,把可行的数字拿出来排个序编个号就好了,表示不会用新...
  • u012288458
  • u012288458
  • 2015-07-29 20:44:22
  • 880

[BZOJ3679][数位DP]数字之积

学一发数位DP 如果直接记录乘积的话有10910^9的情况,但是因为每一位只有1~9,所以最后乘积只有2 3 5 7的质因数,那么把在第i为放0~9转化成放入多少个2 3 5 7 f(i,c2,c...
  • Coldef
  • Coldef
  • 2017-04-12 08:59:04
  • 304

[BZOJ3679]数字之积 数位DP

首先还是ANS[L,R)=ANS[1,R-1]-ANS[1,L-1]。 f[i][j][0/1]表示从高到低填到第i位,积为j的个数。 不过j太大了,但我们发现数字之积分解质因数只可能有2,3,5...
  • DOFYPXY
  • DOFYPXY
  • 2017-10-17 19:13:36
  • 100

[bzoj3679]数字之积

题目大意一个数x各个数位上的数之积记为f(x) 求[L,R)中满足0 < f(x)
  • WorldWide_D
  • WorldWide_D
  • 2016-12-08 15:41:01
  • 527

BZOJ3679: 数字之积

我们会发现对于一个乘积一定可以分解为2 3 5 7的倍数然后就根据这个来做了预处理出每个数的幂次总感觉数位DP用记忆化搜索更方便?#include #include #include #include...
  • liutian429073576
  • liutian429073576
  • 2016-03-23 12:48:03
  • 347

BZOJ3679 数字之积

3679: 数字之积 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 415 Solved: 195 [Submit][Status][Dis...
  • Aqua_blue
  • Aqua_blue
  • 2017-07-28 13:45:37
  • 148

51Nod 数字0到9的数量 (数位DP)

跟1009题类似: http://blog.csdn.net/since_natural_ran/article/details/72668443但是还是这道题考察能力强。 对于数字的考察...
  • Since_natural_ran
  • Since_natural_ran
  • 2017-06-06 21:44:16
  • 260
    个人资料
    持之以恒
    等级:
    访问量: 8761
    积分: 733
    排名: 6万+
    文章存档
    最新评论