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 }