abc135D 模13余5的数的个数

64 阅读1分钟

题面:给定一个由0~9以及?组成的字符串,其中的?可以替换成0~9中任意1个数字,问有多少种情况使得这个数字模13的余数为5?结果对1e9+7取模。注意允许s有前导0。

范围:1 <= |s| <= 1E5

分析:记dp[i][j]表示前i个数字构成的数模13余j的方案数。如果s[i]是数字,直接转移;如果是问号,枚举0~9所有可能分别转移,总时间复杂度O(13n)。这里使用的是刷表法。

#include <bits/stdc++.h>
// mint模板略
const int N = 100005;
mint dp[N][13];
void solve() {
    std::string s;
    std::cin >> s;
    int n = s.size();
    dp[0][0] = 1;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j <= 12; j++) {
        if (s[i] == '?') {
            for (int k = 0; k <= 9; k++) {
                int u = (j * 10 + k) % 13;
                dp[i+1][u] += dp[i][j];
            }
        } else {
            int k = (j * 10 + s[i] - '0') % 13;
            dp[i+1][k] += dp[i][j];
        }
    }
    std::cout << dp[n][5] << "\n";
}

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

标签:线性dp