题意:给定一个int类型能够保存的整数n,求1~n中能被13整除而且包含13的数字的个数。例如13、2613等。
思路:数位dp,模板见hdu3555。这里需要单开一维记录第k位之前的数字除以13的余数。即dfs的m参数。pre参数的意义:0表示之前没有出现过13而且前一位不是1;1表示之前没有出现过13但是前一位为1;2表示之前已经出现过13了。
#include <cstdio>
#include <cstring>
using namespace std;
int n,dp[12][13][3];
int d[12],len;
int dfs(int k,int m,int pre,int limit){
if(k<0)
return m==0 && pre==2;
if(0==limit && dp[k][m][pre]!=-1)
return dp[k][m][pre];
int last = limit?d[k]:9;
int res = 0;
for(int i = 0;i<=last;i++){
int mnow = (m*10+i)%13;
if(pre==0 || (pre==1 && i!=3))
res += dfs(k-1, mnow, i==1, limit&&(i==last));
else
res += dfs(k-1, mnow, 2, limit&&(i==last));
}
if(0==limit)
dp[k][m][pre] = res;
return res;
}
int solve(int x){
len = -1;
while(x){
d[++len] = x%10;
x /= 10;
}
return dfs(len,0,0,1);
}
int main(){
memset(dp,-1,sizeof(dp));
while(scanf("%d",&n)!=EOF)
printf("%d\n",solve(n));
return 0;
}