HDU3652 B-number数位DP+秦九韶算法大数取模

139 阅读1分钟

题目链接 HDU3652

问一个区间内的B-number的数量,B-number的定义是:数位中含有13,另外能被13整数。例如13,130就是B-number。

数位中含有13是数位DP板子,取模使用秦九韶算法。

AC代码:

#include <bits/stdc++.h>
using namespace std;

#define ll long long

ll a[20];
ll dp[11][2][2][13][2];

ll dfs(ll pos, ll limit, ll sta, ll mod, ll flag)//第pos位 有无约束 上一位是否是1 秦九韶mod 前面是否已经包含13
{
    if (pos == 0)
    {
        if (mod == 0 && flag)
            return 1;
        return 0;
    }
    if (!limit && dp[pos][limit][sta][mod][flag] != -1)
        return dp[pos][limit][sta][mod][flag];
    int up = limit ? a[pos] : 9, sum = 0;
    for (int i = 0; i <= up; i++)
        sum += dfs(pos - 1, limit && i == up, i == 1, (mod * 10 + i) % 13, (flag || sta && i == 3));
    if (!limit)
        dp[pos][limit][sta][mod][flag] = sum;
    return sum;
}

ll get(ll x)
{
    memset(dp, -1, sizeof dp);
    ll pos = 0;
    while (x)
    {
        a[++pos] = x % 10;
        x /= 10;
    }
    return dfs(pos, 1, 0, 0, 0);
}
int main()
{
    ll n;
    while (cin >> n)
        cout << get(n) - 0 << endl;
    return 0;
}