题目要求统计小于等于n的既含有子串13,又是13的倍数的数的个数
ans=n-小于等于n的不含子串13或不是13倍数的数的个数
dp[dep][one][thirteen][yu]表示长度为dep,上一个数是否为1,之前的数是否包含13,之前的数模13的余数为yu的数的个数
之前状态没考率全面,狗带了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int dp[15][2][2][13],dig[15]; 4 int dfs(int dep,int one,int thirteen,int yu,int flag){ 5 if(!dep){ 6 if(thirteen)return yu?1:0; 7 else return 1; 8 } 9 if(!flag&&dp[dep][one][thirteen][yu]!=-1)return dp[dep][one][thirteen][yu]; 10 int lim=flag?dig[dep]:9; 11 int ans=0; 12 for(int i=0;i<=lim;i++){ 13 if(one&&i==3)ans+=dfs(dep-1,i==1,1,(yu*10+i)%13,flag&(i==lim)); 14 else ans+=dfs(dep-1,i==1,thirteen,(yu*10+i)%13,flag&(i==lim)); 15 } 16 if(!flag)dp[dep][one][thirteen][yu]=ans; 17 return ans; 18 } 19 int solve(int x){ 20 int dd=0; 21 while(x)dig[++dd]=x%10,x/=10; 22 return dfs(dd,0,0,0,1); 23 } 24 int main(){ 25 memset(dp,-1,sizeof(dp)); 26 int A; 27 while(scanf("%d",&A)!=EOF) 28 printf("%d ",A-solve(A)+1);// 29 return 0; 30 }