hdu 5898 odd-even number (数位dp)
odd-even number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 454 Accepted Submission(s): 245
Problem Description
For a number,if the length of continuous odd digits is even and the length of continuous even digits is odd,we call it odd-even number.Now we want to know the amount of odd-even number between L,R(1<=L<=R<= 9*10^18).
Input
First line a t,then t cases.every line contains two integers L and R.
Output
Print the output for each case on one line in the format as shown below.
Sample Input
2
1 100
110 220
Sample Output
Case #1: 29
Case #2: 36
#include <bits/stdc++.h> using namespace std; #define ll long long int dig[20]; ll dp[20][20][10]; ll dfs(int pos, int len, int oi, int flag0, int lim) { if(pos == -1) return ((len % 2 == 0 && oi % 2 != 0) || (len % 2 != 0 && oi % 2 == 0)); if(!lim && dp[pos][len][oi] != -1) return dp[pos][len][oi]; int End = lim ? dig[pos] : 9; ll ret = 0; for(int i = 0; i <= End; i++) { if(i == 0 && flag0) ret += dfs(pos - 1, 0, 0, 1, (i==End) && lim); else { int nlen, noi; noi = i; if(noi % 2 == oi % 2) nlen = len + 1; else { if(!((len % 2 == 0 && oi % 2 != 0) || (len % 2 != 0 && oi % 2 == 0) || len == 0)) { continue; } else nlen = 1; } ret += dfs(pos - 1, nlen, noi, 0, (i==End) && lim); } } if(!lim) dp[pos][len][oi] = ret; return ret; } ll func(ll num) { int n = 0; while(num) { dig[n++] = num % 10; num /= 10; } return dfs(n - 1, 0, 0, 1, 1); } int main() { int t; scanf("%d", &t); int cas = 0; memset(dp, -1, sizeof(dp)); while(t--) { ll l, r; scanf("%I64d %I64d", &l, &r); printf("Case #%d: %I64d\n", ++cas, func(r) - func(l-1)); } }