数位dp--hdu3652 B-number

来源:互联网 发布:怎么报送发票数据 编辑:程序博客网 时间:2024/05/20 07:32
A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string "13" and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task is to calculate how many wqb-numbers from 1 to n for a given integer n.
 

Input
Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).

求1到n内,出现13并且能被13整除的数的个数。


#include <iostream>

#include <cstring>

using namespacestd;

int bits[12];

int dp[12][13][2][2];


int dfs(int len,int rem,bool occur13,bool state,bool border)//第len位,之前的余数rem,是否已经出现过13,之前一位是不是1,是否在边界

{

    if(!len)return rem == 0 && occur13 ?1 :0;

    if(!border &&dp[len][rem][occur13][state] != -1)return dp[len][rem][occur13][state];

    int res =0,up = border ? bits[len] :9;

    for (int i = 0; i <= up; i ++) {//要找的就是有13的数字,所以不能像不要62那样,不继续递归,相反,还要记录是否已经出现了13,如果已经出现,之后就不需要继续找13

        res += dfs(len -1, (rem * 10 + i) %13, occur13 || (state && i ==3),i == 1, border && i == up);

    }

    if(!border)dp[len][rem][occur13][state] = res;

    return res;

}

int getbits(int n)

{

    int len =0;

    while(n)

    {

        bits[++len] = n %10;

        n /= 10;

    }

    return len;

}

int f(int n)

{

    returndfs(getbits(n),0,0,0,1);

}

int main()

{

    int n;

    memset(dp, -1,sizeof(dp));

    while (cin >> n) {

        cout <<f(n) << endl;

    }

    return0;

}


附上不要62的代码做对比。

#include <iostream>

#include <cstring>

using namespacestd;

const int maxn =25;

int bits[maxn];

int dp[8][2];


int dfs(int len,bool state,bool border)//边界

{

    if(!len)return 1;

    if(!border &&dp[len][state] != -1)return dp[len][state];

    int res =0,up = border ? bits[len] :9;

    for (int i =0; i <= up; i ++) {

        if(i ==4 || (i == 2 && state))continue;//因为不希望有462,所以如果出现,就不继续递归了

        res += dfs(len -1, i == 6, border && i == up);

    }

    if(!border)dp[len][state] = res;//在不处于边界时计数,因为边界仅仅一个数。

    return res;

}

int getbits(int a)

{

    memset(bits,0, sizeof(bits));

    int cnt =0;

    while (a) {

        bits[++ cnt] = a %10;

        a /= 10;

    }

    return cnt;

}

int f(int a)

{

    returndfs(getbits(a),0,1);

}

int main()

{

    int n,m;

    memset(dp, -1,sizeof(dp));

    while (cin >> n >> m) {

        if(n ==0 && m == 0)return 0;

        cout <<f(m) - f(n -1) << endl;

    }

    return0;

}


原创粉丝点击