题目大意
求n以内被13整除且含连续字符串13的数个数,多组数据。
思路
设
f
i
,
j
,
k
f_{i,j,k}
fi,j,k为前i位,%13=j,字符串包含情况为k的个数。
k=0:已带有13字符串
k=1:i位为1
k=2:无连续13且第i位不为1。
然后套路。
code:
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
using namespace std;
int r,f[35][21][21],tot,lyw[35];
inline int dfs(int pos,int x,bool tjh,int wj)
{
if (!tjh&&f[pos][x][wj]!=-1)
{
return f[pos][x][wj];
}
if (!pos&&!wj&&!x) return 1;
if (!pos) return 0;
int mx=tjh?(r/lyw[pos-1]%10):9;
int ans=0;
for (int i=0;i<=mx;i++)
{
int res=(x+13-i*lyw[pos-1]%13)%13;
if (wj==2)
{
ans+=dfs(pos-1,res,tjh&&(i==mx),2);//即使当前位为1,依然跑2情况
if (i==1) ans+=dfs(pos-1,res,tjh&&(i==mx),1);//若为1,也可以被1情况转移(考虑倒着dp)
}
if (wj==1)
{
if (i==3) ans+=dfs(pos-1,res,tjh&&(i==mx),0)+dfs(pos-1,res,tjh&&(i==mx),1);//只有3时可以转移
}
if (wj==0)
{
if (i!=1&&i!=3) ans+=dfs(pos-1,res,tjh&&(i==mx),1);//若为1,不能从1情况转移
if (i!=3) ans+=dfs(pos-1,res,tjh&&(i==mx),0);//若为3,显然无法转移
}
}
if (!tjh) return f[pos][x][wj]=ans;
else return ans;
}
inline int kyx(int r)
{
if (r==0) return 0;
tot=0;
while (r!=0)
{
++tot;
r/=10;
}
int ans=0;
ans+=dfs(tot,0,1,2);
return ans;
}
int main()
{
lyw[0]=1;
for (int i=1;i<=13;i++) lyw[i]=lyw[i-1]*10;
memset(f,-1,sizeof(f));
while (~scanf("%d",&r))
{
printf("%d\n",kyx(r));
}
return 0;
}