bzoj1833: [ZJOI2010]count 数字计数

数位dp。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

long long pow[15],f[15][10][10],resa[10],resb[10];
long long a,b;

void add(long long a[],long long b[]) {
    for(int i=0;i<=9;i++) a[i]+=b[i];
}

void calc(long long a[],long long n) {
    if(!n) {a[0]=1; return;}
    
    int len=14,cur;
    while(pow[len]>n) len--;
    for(int i=1;i<len;i++)
    for(int j=1;j<=9;j++)
        add(a,f[i][j]);
    a[0]++;
    for(int i=len;i;i--) {
        cur=n/pow[i]; n%=pow[i];
        for(int d=(i==len);d<cur;d++)
            add(a,f[i][d]);    
        a[cur]+=n+1;
    }
        
    
}


int main () {
    pow[1]=1;
    for(int i=2;i<=14;i++) pow[i]=pow[i-1]*10;
    
    for(int i=0;i<=9;i++) f[1][i][i]=1;
    
    for(int i=2;i<=12;i++)
    for(int cur=0;cur<=9;cur++)
    for(int last=0;last<=9;last++) {
        add(f[i][cur],f[i-1][last]);
        f[i][cur][cur]+=pow[i-1];
    }
    scanf("%lld%lld",&a,&b);
    calc(resa,a-1);
    calc(resb,b);
    for(int i=0;i<=9;i++) {
        if(i) printf(" ");
        printf("%lld",resb[i]-resa[i]);    
    }
    return 0;
}
原文地址:https://www.cnblogs.com/invoid/p/5495333.html