B-number [HDU 3652]
http://acm.hdu.edu.cn/showproblem.php?pid=3652
View Code
//dp[i][j][3] //表示前i个字符,余数为j //0 存在13,1前一个是1 ,2什么都没有 const int MM = 1111; typedef __int64 int64; #define debug puts("wrong") #define mod 13 int N,M; int num[MM], cnt; int dp[11][15][3]; //0 have 13 // 1 pre=1 // 2 no int dfs(int le,int r,int pre,bool less) { //less前一位是否取到最大e=less?num[le]:9 if(le==-1) return pre==0 && r==0; //边界条件,特定题目 if(!less && dp[le][r][pre]!=-1) return dp[le][r][pre]; int res=0,d, e=less?num[le]:9; for(d=0;d<=e;d++) { int tmp=pre; if(tmp!=0) { if(pre==1 && d==1) tmp=1; else if(pre==1 && d==3) tmp=0; else if(pre==1 && d!=3 && d!=1) tmp=2; else if(pre==2 && d==1) tmp=1; else tmp=2; } res+=dfs(le-1,(r*10+d)%mod,tmp,less&&d==e); } if(!less) dp[le][r][pre]=res; return res; } int cal(int x) { for(cnt=0 ;x; num[cnt++]=x%10,x/=10); return dfs(cnt-1,0,2,true); } void solve() { int i,j,k; printf("%d\n",cal(N)); } int main() { // int ca; scanf("%d",&ca); memset(dp,-1,sizeof(dp)); while(scanf("%d",&N)!=EOF) solve(); return 0; }