题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3652
/*
dp[len][mod][status]
len表示当前位数,mod表示当前的总余数(从高位开始算)
status=0:从最高位到i为没有出现13;
status=1:没有出现13,第i为为1;
status=2:出现13;
*/
#include <stdio.h>
#include <string.h>
int dp[12][15][3],digits[12];
int DFS(int pos,int mod,int status,int limit)
{
int i,have,end,sum,nmod;
if(pos<=0)
return (status==2&&mod==0);//含有13且被13整除
if(!limit&&dp[pos][mod][status]!=-1)//没有上限并且已被访问过
return dp[pos][mod][status];
end=limit?digits[pos]:9;
sum=0;
for(i=0;i<=end;++i)
{
nmod=(mod*10+i)%13;
have=status;
if(status==1&&i!=1)
have=0;
if(status==0&&i==1)
have=1;
if(status==1&&i==3)
have=2;
sum+=DFS(pos-1,nmod,have,limit&&i==end);
}
if(!limit)
dp[pos][mod][status]=sum;
return sum;
}
int main()
{
int n,len,ans;
while(scanf("%d",&n)!=EOF)
{
len=0;
memset(dp,-1,sizeof(dp));
memset(digits,0,sizeof(digits));
while(n)
{
digits[++len]=n%10;
n/=10;
}
ans=DFS(len,0,0,1);
printf("%d\n",ans);
}
return 0;
}