数位DP

#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;
}

你可能感兴趣的:(ACM,codeforces)