题目链接:https://loj.ac/problem/10166
题目大意
求区间[a,b]有多少数字满足数位加和%N等于0。
解题思路
看范围,很明显的数位dp。我们设定状态dp[pos][N][i]表示在%N的情况下,到第pos位,数位加和%N是i,会有多少数字满足数位加和%N等于0。
之后就是很easy的套模板环节。
AC代码
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[40][105][105];//dp[pos][N][i]表示在%N情况下到第pos位数位之和%N为i的满足条件有多少
int a[40];
int x,y,N,cnt;
void init(int n)
{
cnt=0;
while(n)
{
a[++cnt]=n%10;
n/=10;
}
}
int dfs(int pos,int limit,int mod)
{
if(!pos)
return mod==0;
if(!limit&&dp[pos][N][mod]!=-1)
return dp[pos][N][mod];
int up=limit?a[pos]:9;
int ans=0;
for(int i=0;i<=up;++i)
{
ans+=dfs(pos-1,limit&&i==up,(mod+i)%N);
}
if(!limit)
dp[pos][N][mod]=ans;
return ans;
}
int main()
{
memset(dp,-1,sizeof(dp));//别忘记初始化
while(~scanf("%d%d%d",&x,&y,&N))
{
init(x-1);
int l=dfs(cnt,1,0);
init(y);
int r=dfs(cnt,1,0);
printf("%d\n",r-l);
}
return 0;
}