Loading

BZOJ 1026:windy数(数位DP)

http://www.lydsy.com/JudgeOnline/problem.php?id=1026

1026: [SCOI2009]windy数

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 5561  Solved: 2493
[Submit][Status][Discuss]

Description

  windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,
在A和B之间,包括A和B,总共有多少个windy数?

Input

  包含两个整数,A B。

Output

  一个整数

Sample Input

【输入样例一】
1 10
【输入样例二】
25 50

Sample Output

【输出样例一】
9
【输出样例二】
20

HINT

【数据规模和约定】

100%的数据,满足 1 <= A <= B <= 2000000000 。

 

题意比较简单,这里有点蛋疼的是第一个样例我一开始看不懂,然后问了别人才知道例如第一个样例 1 10 的答案是 1 - 9。
所以可能最高位如果前面都是零的话,那么它可以任意选择一个数(0 - 位上限)
如果最高位前面不全都是零的话,那么它就要按照规则即和前一位相差2来取。
还是太弱了。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 #define N 35
 8 //long long dp[N][15][2][2];
 9 long long dp[N][15][2];
10 int bit[N];
11 /*
12 zero判断前面是不是全都是 0,
13 1的话说明前面没有前导零,有值
14 0的话说明前面没有值,都是零
15 */
16 //我一开始的写法
17 //long long dfs(int pos, int pre, int  st, int zero, int flag)
18 //{
19 //    if( !pos ) return st;
20 //    if( zero && !flag && dp[pos][pre][st][zero] != -1 ) return dp[pos][pre][st][zero];
21 //
22 //    long long ans = 0;
23 //    int u = flag ? bit[pos] : 9;
24 //
25 //    if( zero == 0 ){
26 //        for(int i = 0; i <= u; i++){
27 //            ans += dfs(pos - 1, i, i == 0 ? 0 : 1, i == 0 ? 0 : 1, flag && i==u);
28 //        }
29 //    }
30 //    else{
31 //        for(int i = 0; i <= u; i++){
32 //            if( abs(pre - i) >= 2 ){
33 //                ans += dfs(pos - 1, i, 1, 1, flag && i==u);
34 //            }
35 //        }
36 //    }
37 //
38 //    if( zero && !flag ) dp[pos][pre][st][zero] = ans;
39 //    return ans;
40 //}
41 //看了别人的写法,简化了很多
42 long long dfs(int pos, int pre, int zero, int flag)
43 {
44     if( !pos ) return 1;
45     if( zero && !flag && ~dp[pos][pre][zero] ) return dp[pos][pre][zero];
46 
47     long long ans = 0;
48     int u = flag ? bit[pos] : 9;
49 
50     for(int i = 0; i <= u; i++){
51         if( !zero || abs(pre - i) >= 2 )
52 /*
53 例如第一个样例 1 10 的答案是 1 - 9
54 所以可能最高位如果前面都是零的话,那么它可以任意选择一个数(0 - u)
55 如果最高位前面不行全都是零的话,那么它就要按照规则即和前一位相差2来取
56 这一题的没有前导零还有第一个样例搞得我很迷糊。我还是太弱了
57 */
58             ans += dfs(pos - 1, i, i || zero, flag && i==u);
59     }
60     if( !flag ) dp[pos][pre][zero] = ans;
61     return ans;
62 }
63 
64 long long solve(long long x)
65 {
66     int l = 0;
67     while(x>0){
68         bit[++l] = x % 10;
69         x /= 10;
70     }
71 //    return dfs(l, 0, 0, 0, 1);
72     return dfs(l, 0, 0, 1);
73 }
74 
75 int main()
76 {
77     long long a, b;
78     cin >> a >> b;
79     memset(dp, -1, sizeof(dp));
80     if(a > b) swap(a, b);
81 //    cout << solve(b) <<  "  " << solve(a-1) << endl;
82     cout << solve(b) - solve(a-1) << endl;
83     return 0;
84 }

 

posted @ 2016-07-18 12:18  Shadowdsp  阅读(207)  评论(0编辑  收藏  举报