HDU 3652 B-number(数位DP模板题)

来源:互联网 发布:斑马标签打印机软件 编辑:程序博客网 时间:2024/06/17 21:30

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3652


Problem Description
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).
 

Output
Print each answer in a single line.
 

Sample Input
131002001000
 

Sample Output
1122
 

Author
wqb0039
 

Source
2010 Asia Regional Chengdu Site —— Online Contest

题意:

求0 到n中数字含有13且能被13整除的数目!

PS:

数位DP模板题!

取余时用秦九韶算法!

代码如下:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define LL __int64LL n, dp[25][13][3];//dp[i][mod][j]:长度为i,余数为mod,状态为j,int digit[25];//nstatus: 0:不含13, 1:不含13但末尾是1, 2 :含13LL DFS(int pos, int mod, int status, int limit){    if(pos <= 0) // 如果到了已经枚举了最后一位,并且在枚举的过程中有49序列出现        return status==2 && mod==0;//注意是 ==    if(!limit && dp[pos][mod][status]!=-1)   //对于有限制的询问我们是不能够记忆化的        return dp[pos][mod][status];    LL ans = 0;    int End = limit?digit[pos]:9;   // 确定这一位的上限是多少    for(int i = 0; i <= End; i++)   // 每一位有这么多的选择    {        int nmod = (mod*10+i)%13;        int nstatus = status;       // 有点else s = statu 的意思        if(status==0 && i==1)//高位不含13,并且末尾不是1,现在末尾添1返回1状态            nstatus = 1;        else if(status==1 && i!=1 && i!=3)//高位不含13,且末尾是1,现在末尾添加的不是1返回0状态            nstatus = 0;        else if(status==1 && i==3)//高位不含13,且末尾是1,现在末尾添加3返回2状态            nstatus = 2;        ans+=DFS(pos-1, nmod, nstatus, limit && i==End);    }    if(!limit)        dp[pos][mod][status]=ans;    return ans;}int cal(LL x){    int cnt = 0;    while(x)    {        digit[++cnt] = x%10;        x/=10;    }    digit[cnt+1] = 0;    return cnt;}int main(){    while(~scanf("%I64d",&n))    {        memset(dp,-1,sizeof(dp));        int len = cal(n);        LL ans = DFS(len, 0, 0, 1);        printf("%I64d\n",ans);    }    return 0;}


0 0