题目链接:https://cn.vjudge.net/problem/CodeForces-1036C
题目大意:求l到r之间,数位上不超过三个非零数字的数的个数。
分析:dp[i][j][k]表示,还剩i位,有没有限制,出现了几个非零数字。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll dp[25][2][4];
int digit[25];
ll dfs(int len, int sum, int limit)
{
if(len < 0) return 1;
if(dp[len][limit][sum]) return dp[len][limit][sum];
if(sum >= 3) return dp[len][limit][sum] = 1;
ll cnt = 0;
int p = limit ? digit[len] : 9;
for(int i = 0; i <= p; i++)
{
cnt += dfs(len - 1, sum + (i == 0 ? 0 : 1), (i == p) && limit);
}
return dp[len][limit][sum] = cnt;
}
ll solve(ll n)
{
int k = 0;
memset(dp, 0, sizeof dp);
while(n)
{
digit[k++] = n % 10;
n /= 10;
}
return dfs(k - 1, 0, 1);
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
ll l, r;
scanf("%lld %lld",&l, &r);
printf("%lld\n", solve(r) - solve(l - 1));
}
return 0;
}