[Digital dp] spoj 10738 Ra-One Numbers, spoj10738
Given x and y, the number of even digits between [x, y] is equal to or equal to one minus odd digits.
One digit is the first.
Example: 10 = 1-0 = 1 so 10 is such a number
Idea: digit dp [I] [sum] [OK] I bit and sum whether there is a leading 0.
Then, because there is a negative number, 0 is set to 100 Based on the range, and then the last and equal to 101 are the numbers.
Code:
[Cpp]View plaincopyprint?
- # Include "cstdlib"
- # Include "cstdio"
- # Include "cstring"
- # Include "cmath"
- # Include "stack"
- # Include "algorithm"
- # Include "iostream"
- Using namespace std;
- Int dp [12] [200] [2], num [12];
- Int fuck [2] = {1,-1 };
- Int dfs (int site, int sum, int OK, int f)
- {
- If (site = 0)
- {
- If (OK = 0) return 0;
- Return sum = 101? 1:0; // The sum of small processing and 101
- }
- If (! F & dp [site] [sum] [OK]! =-1) return dp [site] [sum] [OK];
- Int len = f? Num [site]: 9;
- Int ans = 0;
- For (int I = 0; I <= len; I ++)
- {
- If (OK = 0)
- {
- If (I = 0) ans + = dfs (site-1, sum, OK | I! = 0, f & I = len );
- Else ans + = dfs (site-1, sum + I * fuck [site % 2], OK | I! = 0, f & I = len );
- }
- Else
- {
- Ans + = dfs (site-1, sum + I * fuck [site % 2], OK | I! = 0, f & I = len );
- }
- }
- If (! F) dp [site] [sum] [OK] = ans;
- Return ans;
- }
- Int solve (int x)
- {
- If (x <0) return 0;
- Int cnt = 0;
- While (x)
- {
- Num [++ cnt] = x % 10;
- X/= 10;
- }
- Return dfs (cnt, 100, 0, 1); // sum =
- }
- Int main ()
- {
- Int t;
- Scanf ("% d", & t );
- Memset (dp,-1, sizeof (dp ));
- While (t --)
- {
- Int x, y;
- Scanf ("% d", & x, & y );
- Printf ("% d \ n", solve (y)-solve (x-1 ));
- }
- Return 0;
- }