Transmission Door
This problem is a digital DP entry question.
What is a digital DP? In simple terms, a digital DP is a DP that is used to solve a given interval and how many numbers satisfy a condition. The number of numbers is irrelevant to the size of the number and is related to the structure of the numbers. We first calculate the number of eligible in [0,r], and then calculate the number of conditions in [0,L-1].
In this case, in fact, the DP between the number is very good to think, we enumerate the adjacent two-bit, matching the conditions to the number of these programs are all added. So we set DP[I][J] to indicate the number of J, with J as the highest bit, and how many windy number.
Then the equation is dp[i][j] = Sigma (Dp[i-1][k]), wherein ABS (K-J) >= 2;
The question after that is, how do we find out how many of the numbers fit within a range?
Here is a way to calculate the number of conditions that can be calculated [0,l] as long as the corresponding +1 can be calculated.
For a number, we put it every bit in a cell that has an array. First of all, for each length is smaller than the current number, we all add, because it must be compliant (note that the first bit cannot be 0). Then for the same number of bits, we just start with the high position and enumerate which one is less than the current number. This will always be enumerated to the last one. Note that there are two conditions that must be met, and the first one must be from the second bit to make sure that every bit of your current enumeration is equal to or greater than the absolute value of the previous bit, or else you count the illegal situation. The second is that your current boundaries must meet the criteria themselves, otherwise you are the equivalent of being statistically illegal.
That's OK. Understand the code.
#include <iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<queue>#include<cstring>#defineRep (i,a,n) for (int i = a;i <= n;i++)#definePer (i,n,a) for (int i = n;i >= a;i--)#defineEnter Putchar (' \ n ')using namespaceStd;typedefLong Longll;Const intM =1000005;inta,b,dp[ -][ -],ans,af[ -],len;intRead () {intAns =0, op =1; CharCH =GetChar (); while(Ch <'0'|| CH >'9') { if(ch = ='-') op =-1; CH=GetChar (); } while(Ch >='0'&& CH <='9') {ans*=Ten; Ans+ = CH-'0'; CH=GetChar (); } returnAns *op;}voidInit () {Rep (I,0,9) dp[1][i] =1;//0~9 are windy numbers .Rep (I,2,Ten) Rep (p,0,9) Rep (q,0,9) { if(ABS (P-Q) <2)Continue; DP[I][P]+ = dp[i-1][Q];//here is the digital DP }}intSolveintx) { intCur =0; memset (AF,0,sizeof(AF)); Len =0; while(x) {af[++len] = x%Ten; X/=Ten;//to split a number} rep (I,1, len-1) Rep (J,1,9) cur + = Dp[i][j//calculate the number of all bits less than it is];Rep (I,1, af[len]-1) cur + = dp[len][i];//First placePer (i,len-1,1)//start with the second place{Rep (J,0, af[i]-1) { if(ABS (j-af[i+1]) <2)Continue; Cur+ = Dp[i][j];//plus the legal situation . } if(ABS (af[i+1]-af[i]) <2) Break;//if the original number is illegal, jump out . } returncur;}intMain () {a= Read (), B =read (); Init (); Ans= Solve (b +1) -solve (a); printf ("%d\n", ans); return 0;}
SCOI2009 Windy Number