Consider the decimal presentation of an integer. Let's call a number d-magic if digit d appears in decimal presentation of the number on even positions and nowhere else.
For example, the numbers 1727374, 17, 1 are 7-magic but 77, 7, 123, 34, 71 are not 7-magic. On the other hand the number 7 is 0-magic, 123 is 2-magic, 34 is 4-magicand 71 is 1-magic.
Find the number of d-magic numbers in the segment [a, b] that are multiple of m. Because the answer can be very huge you should only find its value modulo 109 + 7 (so you should find the remainder after dividing by 109 + 7).
The first line contains two integers m, d (1 ≤ m ≤ 2000, 0 ≤ d ≤ 9) — the parameters from the problem statement.
The second line contains positive integer a in decimal presentation (without leading zeroes).
The third line contains positive integer b in decimal presentation (without leading zeroes).
It is guaranteed that a ≤ b, the number of digits in a and b are the same and don't exceed 2000.
Print the only integer a — the remainder after dividing by 109 + 7 of the number of d-magic numbers in segment [a, b] that are multiple of m.
分析:这是一道数位DP题。数位DP题的基本特性是给你两个数,然后在这两个数字之间找到符合约束条件的数的个数,
数位DP有一个模板可以用于套,那么问题的解决就在于DP的过程中对符合条件的数进行筛选,这一题是简单题,DP过
程加个IF语句就可以了。
然后来讲讲在DFS的三个参数值那个jud在算法中的运用,jug=1时表示此时数字是满位,例如考虑数字3的时候,当我对
0,1,2,进行求值的时候,jug就为0了。
jug的值在算法中的记忆化搜索有着重要的地位,为什么在jug=0时可以直接返回dp值而jug=1的时候不可以呢?.主要是
当jug为零的时候是枚举0-9的,而jug=1的是时候只枚举下一位m(0-m),如果在jug=1时也直接返回状态会变多进而
导致答案也比所求答案大,那么就不正确了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2100;
typedef long long LL;
int num[maxn],len;
LL dp[maxn][maxn];
const int MOD=1e9+7;
char ax[maxn],bx[maxn];
int m,d;
LL dfs(int pos,int ok,int jud)
{
if(pos==len)return ok==0;
if(!jud&&dp[pos][ok]!=-1)return dp[pos][ok];
LL ans=0;
int sz=jud?num[pos]:9;
for(int i=0;i<=sz;i++)
{
if(pos%2==0&&i==d)continue;
if(pos%2!=0&&i!=d)continue;
ans+=dfs(pos+1,(ok*10+i)%m,jud&&(sz==i));
ans%=MOD;
}
if(!jud)
dp[pos][ok]=ans;
return ans;
}
LL Cou(char* s)
{
int pos=0;
for(int i=0;i<len;i++)
{
int index=s[i]-'0';
num[i]=index;
}
return dfs(0,0,1);
}
int jud(char* s)
{
int temp=0;
for(int i=0;i<len;i++)
{
num[i]=s[i]-'0';
if(num[i]==d&&i%2==0)
return 0;
if(num[i]!=d&&i%2==1)
return 0;
temp=(temp*10+num[i])%m;
}
return temp==0;
}
int main()
{
memset(dp,-1,sizeof(dp));
scanf("%d%d",&m,&d);
scanf("%s%s",&ax,&bx);
len=strlen(ax);
//cout<<Cou(ax)<<endl;
printf("%d",(Cou(bx)%MOD-Cou(ax)%MOD+jud(ax)+MOD)%MOD);
return 0;
}