#include <bits/stdc++.h>
using namespace std;
long long dp[22][10];
int digit[20];
/// 对于一般的数 只要第一个数字确定了 如果成立的话 最后一个数字只有一种情况 所以只能返回0或1
/// 但是对于以0开头而且只有最后一个数字不为0的数而言 也只是加上1这就不正确 少加了8个
long long DFS(int pos, int begin, int flag)
{
if(dp[pos][begin] != -1 && !flag)
return dp[pos][begin];// n 位到 pos 位的数字已经确定 判断这样满足条件的个数
int end = flag ? digit[pos] : 9;
if(pos == 0) return begin <= end;
long long ans = 0;
for(int i=0; i<=end; i++)
ans += DFS(pos-1, begin, i==end && flag);
if(!flag)
dp[pos][begin] = ans;
return ans;
}
long long cal(long long n)
{
int pos = 0;
if(!n) return 0;
while(n)
{
digit[pos++] = n%10;
n /= 10;
}
if(pos == 1) return digit[0];
long long ans = 0;
for(int i=0; i<=digit[pos-1]; i++)
ans += DFS(pos-2, i, i==digit[pos-1]);
return ans + 8;
}
int main()
{
long long l, r;
memset(dp, -1, sizeof(dp));
cin>>l>>r;
cout<<cal(r) - cal(l - 1)<<endl;
return 0;
}
数位DP
最新推荐文章于 2025-08-20 12:30:00 发布

1554

被折叠的 条评论
为什么被折叠?



