BZOJ -1799 self 同類分佈
阿新 • • 發佈:2018-12-13
Description
給出a,b,求出[a,b]中各位數字之和能整除原數的數的個數。
Sample Input
10 19
Sample Output
3
HINT
【約束條件】1 ≤ a ≤ b ≤ 10^18
思路:
數位dp,dp[i][j][k]表示第i位,j表示當前餘數,k表示第i位的數字。
for (int i = 1; i <= pos * 9; i++)中的pos * 9是每一位數字的和的最大值。
#include <cstdio> #include <iostream> #include <cstring> using namespace std; typedef long long ll; ll a[20], dp[20][180][180]; ll dfs(int pos, int p, int sta1, int sta2, bool limit) { if (pos == -1) { return (sta1 == 0 && sta2 == p); } if (sta2 > p || sta2 + (pos + 1) * 9 < p) { return 0; } if (!limit && dp[pos][sta1][sta2] != -1) { return dp[pos][sta1][sta2]; } int up = limit ? a[pos] : 9; ll result = 0; for (int i = 0; i <= up; i++) { result += dfs(pos - 1, p, (sta1 * 10 + i) % p, sta2 + i, limit && (i == a[pos])); } if (!limit) { dp[pos][sta1][sta2] = result; } return result; } ll solve(ll x ) { int pos = 0; ll up = x; while (x > 0) { a[pos] = x % 10; x /= 10; pos++; } ll result = 0; cout << "pos * 9 = " << pos * 9 << endl; for (int i = 1; i <= pos * 9; i++) { memset(dp, -1, sizeof(dp)); result += dfs(pos - 1, i, 0, 0, 1); } return result; } int main() { ll l, r; cin >> l >> r; cout << solve(r) - solve(l - 1) << endl; return 0; }