【题解】 P4127 [AHOI2009]同类分布
\(Description:\)
给出两个数a,b,求出\([a,b]\)中各位数字之和能整除原数的数的个数。
$Sample $ \(Input:\)
10 19
\(Sample\) \(Output:\)
3
\(Solution:\)
设计状态 \(f[len][sum][res]\) 表示倒数还有 \(i\) 位要做,当前的和是 \(sum\) ,摸掉模数后剩下的数是 \(res\),
那么我们直接暴力枚举模数,\(len=0\) 最后判断一下是否 \(sum=mod\) \(\&\&\) \(res=0\) 这个时候可以吧答案返回为 \(1\) 。
那么再套个板子就。。。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a,b;
const int N=20+1,M=200+1;
int f[N][M][M],digit[N];
inline int dfs(int len,int sum,int res,int p,bool limit){
if(len==0) {
if(res==0) return (sum==p)?1:0;// 答案的判断,以为这样写可以加速,实际上变慢了。。。
return 0;
}
if(!limit && f[len][sum][res]!=-1) return f[len][sum][res];
int ret=0,up_bound=(limit)?digit[len]:9;
for(int i=0;i<=up_bound;++i)
ret+=dfs(len-1,sum+i,(res*10+i)%p,p,limit&&i==up_bound);
return f[len][sum][res]=ret;
}
inline int solve(int n){
int cnt=0,ret=0;
while(n){
digit[++cnt]=n%10;
n/=10;
}
for(int p=1;p<=9*cnt;++p){//最多枚举到各位都是9
memset(f,-1,sizeof(f));
ret+=dfs(cnt,0,0,p,true);
}
return ret;
}
signed main(){
scanf("%lld%lld",&a,&b);
printf("%lld\n",solve(b)-solve(a-1));
return 0;
}