学习大神的数位DP模版。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int dp[31][31][31]; 6 int num[31]; 7 //dp[i][j][k] 代表前i位余数为j时候 flag的3种情况 8 int dfs(int pos,int pre,int flag,int bound)//pos代表位置,pre代表余数, 9 { 10 int ans = 0,end,tflag,tpre,i; 11 if(pos == -1)//flag 1代表上位是1,2代表前面已经有13了,0代表其他的。 12 return pre == 0&&flag == 2; 13 if(!bound&&dp[pos][pre][flag] != -1) 14 return dp[pos][pre][flag]; 15 end = bound ? num[pos] : 9; 16 for(i = 0;i <= end;i ++) 17 { 18 tpre = (pre*10 + i)%13; 19 tflag = flag; 20 if(flag == 1&&i == 3) 21 tflag = 2; 22 else if(flag == 0&&i == 1) 23 tflag = 1; 24 else if(flag == 1&&i != 1) 25 tflag = 0; 26 ans += dfs(pos-1,tpre,tflag,bound&&i == end); 27 } 28 if(!bound) 29 dp[pos][pre][flag] = ans; 30 return ans; 31 } 32 int judge(int x) 33 { 34 int pos = 0; 35 while(x) 36 { 37 num[pos++] = x%10; 38 x = x/10; 39 } 40 return dfs(pos-1,0,0,1); 41 } 42 int main() 43 { 44 int n; 45 memset(dp,-1,sizeof(dp)); 46 while(scanf("%d",&n)!=EOF) 47 printf("%d ",judge(n)); 48 return 0; 49 }