Loading

HDU 5787:K-wolf Number(数位DP)

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5787

题意:要求相邻的K个位的数不能相同,在[L,R]区间有多少个这样的数.

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 int bit[20];
 7 long long dp[20][11][11][11][11];
 8 int k;
 9 
10 //考虑前导零:d = 10代表前一位是0, 当(d == 10 && u == 0)表示当前这位为0并且前4位都是0
11 
12 bool check(int a, int b, int c, int d, int u)
13 {
14     if(k == 2) return u != d;
15     else if(k == 3) return u != d && u != c;
16     else if(k == 4) return u != d && u != c && u != b;
17     else return u != d && u != c && u != b && u != a;
18 }
19 
20 long long dfs(int pos, int a, int b, int c, int d, bool flag)
21 {
22     if(pos <= 0) return d != 10;
23     long long res = dp[pos][a][b][c][d];
24     if(flag && res != -1) return res;
25     long long ans = 0;
26     int up = flag ? 9 : bit[pos];
27     for(int u = 0; u <= up; u++) {
28         if(d == 10 && u == 0) {
29             ans += dfs(pos - 1, a, b, c, d, flag || u != up);
30         } else if(check(a, b, c, d, u)) {
31             ans += dfs(pos - 1, b, c, d, u, flag || u != up);
32         }
33     }
34     if(flag) dp[pos][a][b][c][d] = ans;
35     return ans;
36 }
37 
38 long long solve(long long x)
39 {
40     int len = 0;
41     while(x) {
42         bit[++len] = x % 10;
43         x /= 10;
44     }
45     return dfs(len, 10, 10, 10, 10, 0);
46 }
47 
48 int main()
49 {
50     long long l, r;
51     while(~scanf("%I64d%I64d%d", &l, &r, &k)) {
52         memset(dp, -1, sizeof(dp));
53         printf("%I64d\n", solve(r) - solve(l - 1));
54     }
55     return 0;
56 }

 

另一种:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 int bit[20];
 7 long long dp[20][11][11][11][11][2];
 8 int k;
 9 
10 //考虑前导零:d = 10代表前一位是0, 当(d == 10 && u == 0)表示当前这位为0并且前4位都是0
11 
12 bool check(int a, int b, int c, int d, int u)
13 {
14     if(k == 2) return u != d;
15     else if(k == 3) return u != d && u != c;
16     else if(k == 4) return u != d && u != c && u != b;
17     else return u != d && u != c && u != b && u != a;
18 }
19 
20 long long dfs(int pos, int a, int b, int c, int d, bool flag, bool zero)
21 {
22     if(pos <= 0) return zero;
23     long long res = dp[pos][a][b][c][d][zero];
24     if(flag && res != -1 && zero) return res;
25     long long ans = 0;
26     int up = flag ? 9 : bit[pos];
27     for(int u = 0; u <= up; u++) {
28         if(!zero && u == 0) {
29             ans += dfs(pos - 1, a, b, c, d, flag || u != up, 0);
30         } else if(check(a, b, c, d, u)) {
31             ans += dfs(pos - 1, b, c, d, u, flag || u != up, 1);
32         }
33     }
34     if(flag) dp[pos][a][b][c][d][zero] = ans;
35     return ans;
36 }
37 
38 long long solve(long long x)
39 {
40     int len = 0;
41     while(x) {
42         bit[++len] = x % 10;
43         x /= 10;
44     }
45     return dfs(len, 10, 10, 10, 10, 0, 0);
46 }
47 
48 int main()
49 {
50     long long l, r;
51     while(~scanf("%I64d%I64d%d", &l, &r, &k)) {
52         memset(dp, -1, sizeof(dp));
53         printf("%I64d\n", solve(r) - solve(l - 1));
54     }
55     return 0;
56 }

 

posted @ 2016-09-02 15:09  Shadowdsp  阅读(183)  评论(0)    收藏  举报