题意简述
求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));
}