洛谷 P4124 [CQOI2016]手機號碼
阿新 • • 發佈:2018-11-04
題意簡述
求l~r之間不含前導零,至少有三個相鄰的相同數字,不同時含有4和8的11位正整數的個數
題解
數位DP,注意在l,r位數不夠時補至11位
程式碼
#include <cstdio> #include <cstring> typedef long long ll; int cnt; int num[20]; ll l, r; ll dp[20][2][10][10][2][2]; bool _4, _8, _f; ll dfs(int len, int p1, int p2, bool limit, bool lead, bool flag, bool f4, bool f8) { ll s = 0; if (len < cnt && lead) return 0; if (len == 0) return flag; ll& dp = ::dp[len][flag][p1][p2][f4][f8]; if (!limit && ~dp) return dp; int mx = limit ? num[len] : 9; for (register int i = 0; i <= mx; ++i) { if ((i == 4 && f8) || (i == 8 && f4)) continue; _4 = f4 || (i == 4); _8 = f8 || (i == 8); _f = flag || (i == p1 && p1 == p2); s += dfs(len - 1, i, p1, limit && (i == mx), lead && !i, _f, _4, _8); } if (!limit) dp = s; return s; } ll solve(ll x) { cnt = 0; memset(dp, -1, sizeof(dp)); while (x) {num[++cnt] = x % 10; x /= 10; } while (cnt < 11) num[++cnt] = 0; return dfs(cnt, -1, -1, 1, 1, 0, 0, 0); } int main() { scanf("%lld%lld", &l, &r); printf("%lld", solve(r) - solve(l - 1)); }