hdu 3652 数位dp
观察区数字是否含有13并且能被13整除
Sample Input
13
100
200
1000
Sample Output
1
1
2
2
注意在判断新状态的时候顺序不能弄反,否则会把之前的正确状态覆盖
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f3f3f3f; 11 const double eps=1e-5; 12 typedef long long ll; 13 #define cl(a) memset(a,0,sizeof(a)) 14 #define ts printf("*****\n"); 15 const int MAXN=15; 16 int n,m,tt; 17 int dp[MAXN][3][MAXN]; 18 int digit[20]; 19 int dfs(int p,int s,int mod,bool e) { //前一个数的状态,13为2,1X为1,XX为0,之前的数的余数 20 if (p==-1) return s==2&&mod==0; 21 if (!e &&dp[p][s][mod]!=-1) return dp[p][s][mod]; 22 int res = 0; 23 int u = e?digit[p]:9; 24 for (int i=0;i<=u;++i) 25 { 26 int ns=s; 27 if(s==1&&i!=1) ns=0; 28 if(s==0&&i==1) ns=1; 29 if(s==1&&i==3) ns=2; 30 res+=dfs(p-1,ns,(mod*10+i)%13,e&&i==u); 31 } 32 return e?res:dp[p][s][mod]=res; 33 } 34 int solve(int n) 35 { 36 int len=0; 37 while(n) 38 { 39 digit[len++]=n%10; 40 n/=10; 41 } 42 return dfs(len-1,0,0,1); 43 } 44 int main() 45 { 46 int i,j,k; 47 #ifndef ONLINE_JUDGE 48 freopen("1.in","r",stdin); 49 #endif 50 memset(dp,-1,sizeof(dp)); 51 while(scanf("%d",&n)!=EOF) 52 { 53 printf("%d\n",solve(n)); 54 } 55 }