bzoj1026 [SCOI2009]windy数

1026: [SCOI2009]windy数

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 4031  Solved: 1803
[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 。

 

Source

 

题意:不解释

解法:提供两种解法

1、打表,每隔10000000w记录一下1-x*10000000有多少windy数,然后没算到的部分暴力算,算过得直接相减得到答案,显然,每次求解最多运算20000000w次,显然不会超时

2、数位dp,先数位dp  1-(a-1)有多少,再dp 1-b有多少,相减即得答案,没什么要注意的,唯一要注意的就是前面全是零的情况

只给出第二种解法

dp[n][m][2] 第一位表示现在是第几位,第二维表示第i 位填数字几,第三位表示目前填满了没有

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <deque>
 6 #include <vector>
 7 #include <queue>
 8 #include <iostream>
 9 #include <algorithm>
10 #include <map>
11 #include <set>
12 #include <ctime>
13 using namespace std;
14 typedef long long LL;
15 typedef double DB;
16 #define For(i, s, t) for(int i = (s); i <= (t); i++)
17 #define Ford(i, s, t) for(int i = (s); i >= (t); i--)
18 #define Rep(i, t) for(int i = (0); i < (t); i++)
19 #define Repn(i, t) for(int i = ((t)-1); i >= (0); i--)
20 #define rep(i, x, t) for(int i = (x); i < (t); i++)
21 #define MIT (2147483647)
22 #define INF (1000000001)
23 #define MLL (1000000000000000001LL)
24 #define sz(x) ((int) (x).size())
25 #define clr(x, y) memset(x, y, sizeof(x))
26 #define puf push_front
27 #define pub push_back
28 #define pof pop_front
29 #define pob pop_back
30 #define ft first
31 #define sd second
32 #define mk make_pair
33 inline void SetIO(string Name) {
34     string Input = Name+".in",
35     Output = Name+".out";
36     freopen(Input.c_str(), "r", stdin),
37     freopen(Output.c_str(), "w", stdout);
38 }
39 
40 const int N = 15, M = 10;
41 int A, B;
42 int Arr[N], Dp[N][M][2];
43 
44 inline void Input() {
45     scanf("%d%d", &A, &B);
46 }
47 
48 inline int Work(int x) {
49     if(x <= 0) return 0;
50     int Len = 0;
51     for(int t = x; t; t /= 10) Arr[++Len] = t%10;
52     clr(Dp, 0);
53     For(i, 1, Arr[Len]-1) Dp[Len][i][0] = 1;
54     Dp[Len][Arr[Len]][1] = 1;
55     Ford(i, Len-1, 1) {
56         Rep(j, M) {
57             if(Dp[i+1][j][0]) {
58                 For(k, 0, j-2) Dp[i][k][0] += Dp[i+1][j][0];
59                 For(k, j+2, 9) Dp[i][k][0] += Dp[i+1][j][0];
60             }
61             
62             if(Dp[i+1][j][1]) {
63                 int Cnt = min(Arr[i], j-2);
64                 For(k, 0, Cnt) Dp[i][k][k == Arr[i]] += Dp[i+1][j][1];
65                 For(k, j+2, Arr[i]) Dp[i][k][k == Arr[i]] += Dp[i+1][j][1];
66             }
67         }
68         For(j, 1, 9) Dp[i][j][0]++;
69     }
70     
71     int Ret = 0;
72     Rep(i, M) {
73         Ret += Dp[1][i][0];
74         Ret += Dp[1][i][1];
75     }
76     return Ret;
77 }
78 
79 inline void Solve() {
80     if(A > B) swap(A, B);
81     
82     int L = Work(A-1);
83     int R = Work(B);
84     printf("%d\n", R-L);
85 }
86 
87 int main() {
88     SetIO("1026");
89     Input();
90     Solve();
91     return 0;
92 }
View Code

 

posted @ 2015-08-30 20:12  yanzx6  阅读(151)  评论(0编辑  收藏  举报