问一段数字区间满足奇数位大于其相邻偶数位的数有多少,值得注意的是其第0位是最高位不是最低位 - -。
基础的数位DP。dp[19][10][2],分别表示第几位,前一位数是几,这个为是奇数位还是偶数位。
View Code
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> using namespace std; #define LL long long const int Mod = 2520; LL dp[19][10][2]; int num[19]; void init() { memset(dp,-1,sizeof(dp)); } LL dfs(int dep,int pre,int pos,bool doing,LL sum) { if(dep == -1) return 1; if(!doing && dp[dep][pre][pos] != -1) return dp[dep][pre][pos]; LL ans = 0; int end = doing? num[dep]:9; for(int i = 0; i <= end; i++) { LL nowsum = sum * 10 + i; if(nowsum == 0) { ans += dfs(dep - 1, 9, 0,doing && i == end,nowsum); } else if(pos && pre <= i) ans += dfs(dep - 1,i,pos^1,doing && i == end,nowsum); else if(!pos && pre >= i) ans += dfs(dep - 1,i,pos^1,doing && i == end,nowsum); } if(!doing) dp[dep][pre][pos] = ans; return ans; } LL cal(LL x) { if(x < 0) return 0; int i = 0; while(x) { num[i++] = x % 10; x /= 10; } LL ans = 0; ans += dfs(i-1,9,0,1,0); return ans; } int main() { int T; scanf("%d",&T); init(); while(T--) { LL l, r; cin >> l >> r; cout << cal(r) - cal(l-1) << endl; } return 0; }