[BZOJ]1799: [Ahoi2009]self 同类分布 数位DP

5 篇文章 0 订阅

Description

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

题解:

状态还是比较好设计的,关键是转移。一直没有想到怎么转移,看了题解后恍然大悟。只要我们枚举当前的数字和,那么就相当好转移了,因为每一次的模数都是一样的。状态表示以及转移看代码。

代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=162;
LL f[20][165][165][2];//第i位 数字之和为j %当前数字和为k 是(0)否(1)小于当前数 
LL read()
{
    LL x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
LL b[20];
LL solve(LL x)
{
    int ll=0;LL t=x;
    while(t){b[++ll]=t%10;t/=10;}
    reverse(b+1,b+1+ll);
    LL re=0;
    for(int sum=1;sum<=N;sum++)//枚举当前数字和 
    {
        memset(f,0,sizeof(f));
        f[0][0][0][1]=1;
        for(int i=0;i<ll;i++)
        for(int j=0;j<=sum;j++)
        for(int k=0;k<N;k++)
        for(int l=0;l<2;l++)
        if(f[i][j][k][l])
        {
            for(int m=0;m<=((l==0)?9:b[i+1]);m++)
            f[i+1][j+m][(k*10+m)%sum][((l==1&&b[i+1]==m)?1:0)]+=f[i][j][k][l];
        }
        re+=f[ll][sum][0][0]+f[ll][sum][0][1];
    }return re;
}
int main()
{
    LL a=read(),b=read();
    printf("%lld",solve(b)-solve(a-1));
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值