Description
BZOJ4521
Luogu4124
求在([l,r])中有多少个数字满足有3个连续相同数位且不同时出现4和8。
Solution
直接数位DP。
Code
#include <cstdio>
#include <algorithm>
#include <cstring>
typedef long long LL;
LL dp[20][20][20][20][20];
LL a[20];
LL dfs(int pos, int used, int last, int len, bool lead, bool limit, int mxln) {
if (pos == -1) return mxln >= 3;
if (!lead && !limit && dp[pos][used][last][len][mxln] != -1)
return dp[pos][used][last][len][mxln];
int up = limit ? a[pos] : 9;
LL ans = 0;
for (int i = lead; i <= up; ++i) {
if ((used == 4 && i == 8) || (used == 8 && i == 4)) continue;
ans += dfs(pos-1, i==4||i==8 ? i : used, i, i==last?len+1:1, 0, limit&&i==a[pos], std::max(mxln, len+(i==last)));
}
if (!lead && !limit) dp[pos][used][last][len][mxln] = ans;
return ans;
}
LL calc(LL x) {
int pos = -1;
while (x) {
a[++pos] = x % 10L;
x /= 10L;
}
LL ans = pos != 10 ? 0 : dfs(pos, 0, 0, 0, true, true, 0);
return ans;
}
int main() {
memset(dp, -1, sizeof dp);
LL l, r;
scanf("%lld%lld", &l, &r);
printf("%lld
", calc(r) - calc(l-1));
return 0;
}
Note
不要忘了初始化dp
啊!!