HDU-3652 B-number(数位DP)

来源:互联网 发布:蒸汽巴士推荐的淘宝店 编辑:程序博客网 时间:2024/06/04 17:42

题意:

找出1~N中所有既包含13这个子串又可以被13整除的数字个数

思路:

和之前做的数位DP一样,套路同样很强。就是增加了一个余数的记录。并且多加了一个状态

状态一:前面一位是3

状态二:存在13

状态零:前面一位不是1,并且不存在13

(a+b)%mod == ( ( a%mod + b%mod ) ) %mod

#include <stdio.h>#include <iostream>#include <string.h>#include <algorithm >using namespace std;typedef long long ll;int digit[20];ll dp[20][5][20];// i 数位  j状态 k余数ll dfs(int len,int pre,int mod,int limit ){    if(!len)    {        if(pre==2&&!mod)            return 1;        return 0;    }    if(!limit&&dp[len][pre][mod]!=-1)        return dp[len][pre][mod];    ll res=0;    int maxx=limit? digit[len]:9;    for(int i=0;i<=maxx;i++)    {        int mod_x=(mod*10+i)%13;        int pre_x=pre;        if(pre==0)        {            if(i==1)                pre_x=1;        }        if(pre==1)        {            if(i==3)                pre_x=2;            else if(i==1)                pre_x=1;            else pre_x=0;        }        res+=dfs(len-1,pre_x,mod_x,limit&&i==maxx );    }    if(!limit)        dp[len][pre][mod]=res;    return res;}ll solve(ll n){    int len=0;    while(n)    {        digit[++len]=n%10;        n/=10;    }    return dfs(len,0,0,1);}int main(){    ll n;    memset(dp,-1,sizeof(dp));    while(cin>>n)    {        printf("%lld\n", solve(n));    }}


0 0
原创粉丝点击