如果一个十进制数能够被它的各位数字之和整除,则称这个数为“月之数”。
给定整数L和R,你需要计算闭区间[L,R]中有多少个“月之数”。
输入格式
输入占一行,包含两个整数L和R。
输出格式
输出一个整数,表示月之数的个数。
数据范围
1≤L,R<231
输入样例:
1 100
输出样例:
33
思路:
如果记录的是数字大小和数字位总和,最后再来比较,那么就不能实现记忆化(相当于每个数字都判断一遍)
实际的数字位和不大,可以枚举这个数字位和。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int MOD;
int digit[20];
int dp[12][205][205];
int dfs(int len,int mod,int sum,int limit)
{
if(len == 0)
{
if(mod == 0 && sum == MOD)return 1;
else return 0;
}
if(!limit && dp[len][mod][sum] != -1)return dp[len][mod][sum];
int up = limit ? digit[len] : 9;
int ans = 0;
for(int i = 0;i <= up;i++)
{
ans += dfs(len - 1,(mod * 10 + i) % MOD,sum + i,i == up && limit);
}
return limit ? ans : dp[len][mod][sum] = ans;
}
int solve(int x)
{
int cnt = 0;
while(x)
{
digit[++cnt] = x % 10;
x /= 10;
}
int ans = 0;
for(MOD = 1;MOD <= 200;MOD++)
{
memset(dp,-1,sizeof(dp));
ans += dfs(cnt,0,0,1);
}
return ans;
}
int main()
{
memset(dp,-1,sizeof(dp));
int l,r;scanf("%d%d",&l,&r);
printf("%d\n",solve(r) - solve(l - 1));
return 0;
}