洛谷 P4127 [AHOI2009]同类分布

题目传送门

数位dp

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

long long a,b,f[20][2][200][205];
int s[25],len;

inline long long dfs(int d,bool li,long long sum,long long num,long long mm) {
    long long ans = 0;
    if(d == 0 && sum == 0) return 0;
    if(d == 0) return ((sum == mm) && (num == 0)) ? 1 : 0;
    if(f[d][li][sum][num] != -1) return f[d][li][sum][num];
    int res = li ? s[d] : 9;
    for(int i = 0;i <= res; i++)
        ans += dfs(d - 1,li && (i == res),sum + i,(num * 10 + i) % mm,mm);
    f[d][li][sum][num] = ans;
    return ans;
}

inline long long solve(long long x) {
    len = 0;
    long long ret = 0;
    while(x) {
        s[++len] = x % 10;
        x /= 10;
    }
    for(int i = 1;i <= 9 * len; i++) {
        memset(f,-1,sizeof(f));
        ret += dfs(len,1,0,0,i);
    }
    return ret;
} 

int main() {
    scanf("%lld%lld",&a,&b);
    long long ans1 = solve(a - 1);
    long long ans2 = solve(b);
    printf("%lld",ans2 - ans1);
    return 0;
}

 

posted @ 2020-09-02 23:06  Mr^Simon  阅读(95)  评论(0编辑  收藏  举报