hdu 3652 B-number
题意:求小于n,是13的倍数且含有’13’的数的个数。n<1e9
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N=15;
int bit[N],f[N][N][3];
/*
dp[i][j][k] j表示余数
k==0 不包含13且不以1结尾
k==1 不包含13且以1结尾
k==2 包含13
*/
int dfs(int pos,int mod,int have,bool lim)//第几位数,余数,状态标号,是否是上限
{
if(pos<=0)return mod==0&&have==2;
if(!lim&&f[pos][mod][have]!=-1)return f[pos][mod][have];
int num=lim?bit[pos]:9;
int ans=0;
for(int i=0;i<=num;i++){
int mod_x=(mod*10+i)%13; //传到下一位的余数,模拟除法的过程
int have_x=have;
if(have==0&&i==1)have_x=1;//末尾不是1,再加一位是1,标记为1
if(have==1&&i!=1)have_x=0;//末尾是1,再加一位不是1,标记为0
if(have==1&&i==3)have_x=2;//末尾是1,再加一位是3,标记为2
ans+=dfs(pos-1,mod_x,have_x,lim&&i==num);
}
if(!lim)f[pos][mod][have]=ans;
return ans;
}
int main()
{
int n,len;
while(~scanf("%d",&n)){
memset(f,-1,sizeof(f));
len=0;
while(n){
bit[++len]=n%10;
n/=10;
}
printf("%d\n",dfs(len,0,0,1));
}
return 0;
}