BZOJ 1026 [SCOI2009]windy数 - 数位DP

Solution

数位DP板子套上就好了

讲解传送门

Code

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define rd read()
 5 #define ll long long
 6 using namespace std;
 7 
 8 ll sum[15][15];
 9 int a[15];
10 
11 int read() {
12     int X = 0, p = 1; char c = getchar();
13     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
14     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
15     return X * p;
16 }
17 
18 int Abs(int x, int y) {
19     if(x > y) return x - y;
20     else return y - x;
21 }
22 
23 ll dfs(int pos, int pre, bool lim, bool lead) {
24     if(!pos) return 1;
25     if(!lim && !lead && sum[pos][pre] != -1)
26         return sum[pos][pre];
27     int up = lim ? a[pos] : 9;
28     ll tmp = 0;
29     for(int i = 0; i <= up; ++i) {
30         if(Abs(i , pre) < 2) continue;
31         tmp += dfs(pos - 1, (lead && i == 0)? 11 : i, lim && a[pos] == i, lead && i == 0);
32     }
33     if(!lim && !lead) 
34         sum[pos][pre] = tmp;
35     return tmp;
36 }
37 
38 ll work(int x) {
39     int len = 0;
40     while(x) {
41         a[++len] = x % 10;
42         x /= 10;
43     }
44     return dfs(len, 11, true, true);
45 }
46 
47 int main()
48 {
49     int l = rd, r = rd;
50     memset(sum, -1, sizeof(sum));
51     printf("%lld\n", work(r) - work(l - 1));
52 }
View Code

猜你喜欢

转载自www.cnblogs.com/cychester/p/9639220.html