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("*****
");
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
",solve(n));
54     }
55 }
原文地址:https://www.cnblogs.com/cnblogs321114287/p/4267088.html