BZOJ 1026:windy数(数位DP)
http://www.lydsy.com/JudgeOnline/problem.php?id=1026
1026: [SCOI2009]windy数
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 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
1 10
【输入样例二】
25 50
Sample Output
【输出样例一】
9
【输出样例二】
20
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 }