【数位DP】 hdu3652 B-number

B-number

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

题意:问1~n中包含"13"序列且能被13整除的数有多少个。

题解:详情见代码注释。

代码:

#include
#include
using namespace std;
int dp[15][15][3];
/*
dp[i][j][k] j表示余数
k==0 不包含13且不以1结尾
k==1 不包含13且以1结尾
k==2 包含13
*/
int num[15];
int next(int a,int b)
{
    if(a==0)
    {
        if(b==1) return 1;
        else     return 0;
    }
    if(a==1)
    {
        if(b==3) return 2;
        if(b==1) return 1;
        else     return 0;
    }
    return 2;
}
int dfs(int idx,int pre,int value,bool bound)//位数,余数,状态标号,是否为上界
{
    if(idx==-1) return value==2&&pre==0;//数字中出现13且被13整除
    if(!bound&&dp[idx][pre][value]!=-1) return dp[idx][pre][value];//记忆化
    int ans=0,end=bound?num[idx]:9;
    for(int i=0;i<=end;++i)
        ans+=dfs(idx-1,(pre*10+i)%13,next(value,i),bound&&i==end);
    if(!bound) dp[idx][pre][value]=ans;
    return ans;
}
void DP(int n)
{
    int idx=0;
    for(;n;n/=10) num[idx++]=(n%10);
    memset(dp,-1,sizeof(dp));
    printf("%d\n",dfs(idx-1,0,0,true));
}
int main()
{
    int n;
    for(;~scanf("%d",&n);)
       DP(n);
    return 0;
}

来源: http://blog.csdn.net/ACM_Ted

你可能感兴趣的:(ACM,动态规划)