题目链接:hdu 4722
数位dp模板题,顺便把模板写出来了
#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<map>
#include<string.h>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#define LL long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define sqr(a) (a)*(a)
#define lan(a,b) memset(a,b,sizeof(a))
using namespace std;
LL a[20];
LL dp[20][20];
LL pin(int pos,int mor,int lim)
{
if(pos==-1)///递归基,如果所有数位都遍历完毕,判断条件是否满足并返回
{
if(mor==0)
return 1;
return 0;
}
if(dp[pos][mor]!=-1&&!lim) return dp[pos][mor];///记忆化搜索,如果之前搜过就直接返回,前提是lim=0
LL ans=0;
int up=lim?a[pos]:9;///确定上限
for(int i=0;i<=up;i++)
{
ans+=pin(pos-1,(mor+i)%10,lim&&i==up);///dp核心,状态转移
}
if(!lim) dp[pos][mor]=ans;///如果没有限制就更新记忆化数组
return ans;
}
LL sov(LL n)
{
//printf("n=%lld\n",n);
int p=0;
while(n)///处理成数组形式
{
a[p++]=n%10;
n/=10;
}
return pin(p-1,0,1);
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
lan(dp,-1);
LL l,r;
scanf("%I64d%I64d",&l,&r);
LL ans=sov(r);
//printf("ans=%lld\n",ans);
ans-=sov(l-1);
printf("Case #%d: %I64d\n",i,ans);
}
return 0;
}