bzoj 1799: [Ahoi2009]self 同类分布

来源:互联网 发布:mysql 客户端查询乱码 编辑:程序博客网 时间:2024/05/16 08:00

题意

给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数。

题解

枚举那些数加起来是多少,最大是9*18
然后你就可以数位DP了。。
有剩下的数,当前的余数是多少。。
然后就没有了

#include<cstdio>#include<cstring>typedef long long LL;LL A,B;LL n;LL ans=0;LL a[20],o;LL P;//模数是什么LL f[20][9*19][9*19][2]; LL get (LL now,LL x,LL y,bool tf)//现在到第几位   现在的余数是多少   剩下的是多少  是否出现了第一个不同 {    if (y<0) return 0;    if (now<=0)    {        if (y==0&&x==0) return 1;        return 0;    }    if (f[now][x][y][tf]!=-1) return f[now][x][y][tf];    LL lalal=0;    if (tf==false)//不可以越界     {        lalal=lalal+get(now-1,(x*10%P+a[now])%P,y-a[now],false);        for (LL u=0;u<a[now];u++)//这一位填什么            lalal=lalal+get(now-1,(x*10%P+u)%P,y-u,true);     }    else    {        for (LL u=0;u<=9;u++)            lalal=lalal+get(now-1,(x*10%P+u)%P,y-u,true);    }    f[now][x][y][tf]=lalal;    return f[now][x][y][tf];}    LL solve (LL x){    n=x;ans=0;o=0;    while (x>0)    {        a[++o]=x%10;        x/=10;    }    for (LL u=1;u<=9*o;u++)//数位的总和是什么    {        memset(f,-1,sizeof(f));        P=u;        ans=ans+get(o,0,u,false);    }    return ans;}int main(){    scanf("%lld%lld",&A,&B);/*  for (LL u=1;u<=20;u++)        printf("%lld\n",solve(u));*/    printf("%lld\n",solve(B)-solve(A-1));    return 0;}
原创粉丝点击