SPOJ BALNUM - Balanced Numbers_数位dp+三进制压缩

题目连接

题意:A-B中有多少个数满足所有数位上出现的数字,数字为奇数的出现偶数次,数字为偶数的出现奇数次

数位盲打(同hdu352)

0-9每个数字出现的次数状态压缩,0没出现,1出现奇数次,2出现偶数次

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <ctime>
 8 #include <queue>
 9 #include <list>
10 #include <set>
11 #include <map>
12 using namespace std;
13 #define INF 0x3f3f3f3f
14 typedef long long LL;
15 
16 int bit[25];
17 LL dp[25][60000];
18 int Pow(int n, int p)
19 {
20     int res = 1;
21     while(p)
22     {
23         if(p & 1)
24             res *= n;
25         n *= n;
26         p>>=1;
27     }
28     return res;
29 }
30 int change(int state, int n)
31 {
32     int N = n, State = state;
33     while(N--)
34     {
35         State /= 3;
36     }
37     int b = State % 3;
38     if(b<2)
39         return state + Pow(3, n);
40     else
41         return state - Pow(3, n);
42 }
43 int check(int state)
44 {
45     int len=-1, b;
46     while(state)
47     {
48         len++;
49         b = state % 3;
50         if((len & 1)==1 && b == 1)
51             return 0;          
52         if((len & 1)==0 && b == 2)
53             return 0;  
54         state /= 3;
55     }
56     return 1;
57 }
58 LL dfs(int len, int state, int flag)
59 {
60     if(len < 0)
61         return check(state);
62     if(dp[len][state] >= 0 && flag)
63         return dp[len][state];    
64     LL sum = 0;
65     int te = flag ? 9 : bit[len];
66     for(int i = 0; i <= te; i++)
67     {
68         sum+=dfs(len-1, (state==0&&i==0)?0:change(state,i), flag||i<te);
69     }
70     if(flag)
71         dp[len][state] = sum;
72     return sum;
73 }
74 LL solve(LL n)
75 {
76     int len = 0;
77     while(n)
78     {
79         bit[len++] = n % 10;
80         n /= 10;
81     }
82     return dfs(len-1, 0, 0);
83 }
84 int main()
85 {
86     int t;
87     LL A, B;
88     scanf("%d", &t);
89     memset(dp, -1, sizeof(dp));
90     while(t--)
91     {
92         scanf("%lld %lld", &A, &B);
93         LL res = solve(B) - solve(A - 1);
94         printf("%lld\n", res);
95     }
96     return 0;
97 }
View Code

 

posted @ 2016-08-23 15:22  海无泪  阅读(186)  评论(0编辑  收藏  举报