[codeforces] Classy Numbers
题目链接
大致题意:
统计区间[l,r]中,在十进制下表示,出现不超过三个非零数字的个数,例如4,200000,10203
解题思路:
cnt表示非零数字出现的次数,当cnt>3跳过即可
所有能递归到最低位的均为合法情况
状态方程:f[i][j] 表示第i位出现了j个非零数字的数字个数
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 110;
int a[N];
ll f[N][5];
ll dfs(int pos, int limit, int cnt) {
if (pos == -1)return 1;
if (!limit && f[pos][cnt] != -1)return f[pos][cnt];
ll res = 0;
int end = limit ? a[pos] : 9;
for (int i = 0; i <= end; ++i) {
if (i == 0)res += dfs(pos - 1, limit && i == end, cnt);
else if (cnt < 3) res += dfs(pos - 1, limit && i == end, cnt + 1);
}
if (!limit)f[pos][cnt] = res;
return res;
}
ll dp(ll n) {
int len = 0;
while (n) {
a[len++] = n % 10;
n /= 10;
}
return dfs(len - 1, 1, 0);
}
int main(void)
{
memset(f, -1, sizeof f);
int t; scanf("%d", &t);
while (t--) {
ll l, r; scanf("%lld%lld", &l, &r);
printf("%lld\n", dp(r) - dp(l - 1));
}
return 0;
}