hdoj 3652 B-number

来源:互联网 发布:淘宝宝贝详情如何添加 编辑:程序博客网 时间:2024/06/07 03:14

题目链接:B-number

题目大意:给你一个N,问小于等于N的数里面有多少个B-number,B-number的定义是出现13这个子序列并且数位之和为13的倍数

题目思路:数位dp,有没有13我们可以直接去判断,最后能不能被13整除我们在dfs里面定义一个余数去算就好了,2代表有13,1代表前一位是1,0代表都不是,这样就不用像其他的数位dp那样去给一个pre去判断了

#include <map>#include <set>#include <queue>#include <stack>#include <cmath>#include <vector>#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;int digit[200],dp[200][14][3];int dfs(int pos,int mod,int occ,bool limit){    if(pos == -1){        if(mod == 0&occ == 2) return 1;        return 0;    }    if(!limit&&dp[pos][mod][occ] != -1) return dp[pos][mod][occ];    int up = limit?digit[pos]:9;    int ans = 0;    for(int i = 0;i <= up;i++){        int nmod = (mod*10+i)%13;        int nocc = occ;        if(nocc == 1&&i == 3) nocc = 2;        else if(nocc != 2) nocc = (i==1)?1:0;        ans += dfs(pos-1,nmod,nocc,limit&&i == digit[pos]);    }    if(!limit) dp[pos][mod][occ] = ans;    return ans;}int solve(int x){    int pos = 0;    while(x){        digit[pos++] = x%10;        x/=10;    }    return dfs(pos-1,0,0,true);}int main(){    int n;    memset(dp,-1,sizeof(dp));    while(~scanf("%d",&n)){        printf("%d\n",solve(n));    }    return 0;}
原创粉丝点击