题目链接
题目大意
在1<=L<=R<=1e9内,找出有多少个数mod(自己每一位数和)为0
题目思路
显然是数位dp,但是比较巧妙的是要,枚举mod,还有这个卡空间,不能直接return dp[pos][mod][digsum][digmod][limit],就是不要你乘以两倍。。。可以令 dp[pos][mod][digsum][digmod]都为limit==0的时候就行了
注意要memset(dp,-1,sizeof(dp)),因为dp可能是等于0,要不然就会tle
代码
#include<map>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
int t,n,cnt,ans,dig[20],dp[11][82][82][82];
int dfs(int pos,int mod,int digsum,int digmod,bool limit){
if(pos==0){
return digsum==mod&&digmod==0;
}
if(!limit&&dp[pos][mod][digsum][digmod]!=-1){
//注意要memset(dp,-1,sizeof(dp)),因为dp可能是等于0,要不然就会tle
return dp[pos][mod][digsum][digmod];
}
int ans=0;
for(int i=0;i<=9;i++){
if(limit&&i>dig[pos]) break;
ans+=dfs(pos-1,mod,digsum+i,(digmod*10+i)%mod,limit&&i==dig[pos]);
}
if(limit==0){
dp[pos][mod][digsum][digmod]=ans;
}
return ans;
}
int work(int x){
cnt=0,ans=0;
while(x>0){
dig[++cnt]=x%10;
x=x/10;
}
for(int i=1;i<=81;i++){
ans+=dfs(cnt,i,0,0,1);
}
return ans;
}
int main(){
scanf("%d",&t);
memset(dp,-1,sizeof(dp));// !!!!!!!!!!!!!!!!
for(int i=1,a,b;i<=t;i++){
scanf("%d %d",&a,&b);
printf("Case %d: %d\n",i,work(b)-work(a-1));
}
return 0;
}