HDU 3652 B-number(数位DP)

http://acm.hdu.edu.cn/showproblem.php?pid=3652

题意:类似3555,0-n之间某个数中包含13,且整个数能被13整除
分析:数位DP
         同余定理。比如1234对于m取余,相当于123的余数+4在对n取余
         

#include<stdio.h>

#include<string.h>

#define LL long long

const int MN=100;

LL dp[MN][20][10];//位置,余数,状态,刚开始余数那里数组开小了

int digit[MN];



LL DFS(int pos,int mod,int have,int doing)

{

    if(pos==-1) return ((have==2) && (mod==0));

    if(!doing && dp[pos][mod][have]!=-1) return dp[pos][mod][have];

    int end=doing?digit[pos]:9;

    LL ans=0;

    for(int i=0;i<=end;i++)

    {

        int MOD=(mod*10+i)%13;

        int nhave=have;

        if(have==0 && i==1)

           nhave=1;

        if(have==1 && i==3)

           nhave=2;

        if(have==1 && i!=3)

           nhave=0;

        if(have==1 && i==1)

           nhave=1;

        ans+=DFS(pos-1,MOD,nhave,(doing && i==end));

    }

    if(!doing)

    {

        dp[pos][mod][have]=ans;

    }

    return ans;

}



LL cal(LL n)

{

    int len=0;

    while(n)

    {

        digit[len++]=n%10;

        n/=10;

    }

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

    return DFS(len-1,0,0,1);

}



int main()

{

    int i,j;

    LL n;

    while(scanf("%I64d",&n)!=EOF)

    {

        printf("%I64d\n",cal(n));

    }

    return 0;

}
View Code

 

你可能感兴趣的:(number)