HDU 3652 B-number(数位DP)

题目链接:Click here~~

题意:

统计区间 [1,n] 中含有 '13' 且模 13 为 0 的数字有多少个。

解题思路:

dp[len][remain][mask][state] 表示长度为 len,余数为 remain,是否含有 13 为 mask,前缀是否为 1 为 state  ... 的方案数。

Point => 当每位数字都枚举完(即 len = 0)的时候,只有 remain 等于 0 , mask 等于 1 的状态才是有效的。

#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;

int dp[10][13][2][2],digit[10];

int dfs(int len,int remain,bool mask,bool state,bool fp)
{
    if(!len)
        return remain == 0 && mask ? 1 : 0;
    if(!fp && dp[len][remain][mask][state] != -1)
        return dp[len][remain][mask][state];
    int ret = 0 , fpmax = fp ? digit[len] : 9;
    for(int i=0;i<=fpmax;i++){
        ret += dfs(len-1,(remain * 10 + i) % 13,mask || state && i == 3,i == 1,fp && i == fpmax);
    }
    if(!fp)
        dp[len][remain][mask][state] = ret;
    return ret;
}

int f(int n)
{
    int len = 0;
    while(n)
    {
        digit[++len] = n % 10;
        n /= 10;
    }
    return dfs(len,0,0,0,true);
}

int main()
{
    memset(dp,-1,sizeof(dp));
    int n;
    while(~scanf("%d",&n))
    {
        printf("%d\n",f(n));
    }
    return 0;
}


你可能感兴趣的:(HDU 3652 B-number(数位DP))