[BZOJ1026][SCOI2009]windy数
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 。
弱的不行的我第一次自己写数位DP2333...
虽然这只是个数位DP的模板。
f[i][j]表示填到第i位,上一位是j的数的个数。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; #define int long long #define gc getchar() inline int read(){ int res=0;char ch=gc; while(!isdigit(ch))ch=gc; while(isdigit(ch)){res=(res<<3)+(res<<1)+(ch^48);ch=gc;} return res; } #undef gc int l, r; int wei[15], cnt; int f[15][10]; inline int abss(int x){return x<0?-x:x;} int dp(int pos, int last, bool lead, bool limit) { if (pos == -1) return 1; if (!limit and !lead and f[pos][last] != -1) return f[pos][last]; int up = limit ? wei[pos] : 9; int ans = 0; for (int i = 0 ; i <= up ; i ++) { if (abss(i - last) >= 2 or lead) ans += dp(pos - 1, i, lead && i == 0, limit && i == wei[pos]); } if (!limit and !lead) f[pos][last] = ans; return ans; } inline int solve(int x) { cnt = 0; while(x) { wei[cnt++] = x % 10; x /= 10; } return dp(cnt-1, -100, 1, 1); } signed main() { memset(f, -1, sizeof f); l = read(), r = read(); printf("%lld\n", solve(r) - solve(l-1)); return 0; }