- 题解:又是dp想不出来的。(dp_{i, j}) 代表了,第 (i) 位时(从左到右),余数为 (j) 的数量。然后发现,状态转移的时候,如果 $$s_i = ?$$ 则
[dp_{i,(j * 10 + k) \% 13} =sum dp_{i-1, (j * 10 + k) \% 13} (k in [0, 9])
]
否则直接
[dp_{i,(j * 10 + s[i] - '0') \% 13} =sum dp_{i-1, (j * 10 +s[i] - '0') \% 13}
]
- 代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const ll N = 1e6 + 9, mod = 1e9 + 7;
int n;
char s[N];
ll dp[15][N];
ll q_mi(ll a, ll k, ll p) {
ll ret = 1;
ll x = a;
while (k) {
if (k & 1) {
(ret *= x )%= p;
}
(x *= x)%=p;
k >>= 1;
}
return ret;
}
int main() {
cin >> (s + 1);
int n = strlen(s + 1);
dp[0][0] = 1;
for (int i = 1; i <= n; i ++) {
if (s[i] == '?') {
for (int k = 0; k <= 9; k ++)
for (int j = 0; j <= 12; j ++) {
(dp[(j * 10 + k)%13][i] += dp[j][i-1]) %= mod;
}
} else {
for (int j = 0; j <= 12; j++) {
(dp[(j * 10 + s[i] - '0') % 13][i] += dp[j][i - 1]) %= mod;
}
}
//cout << dp[5][i] << endl;
}
cout << dp[5][n] << endl;
}