poj3252 Round Numbers
Combinatorial Math (digital DP)
(I did not expect to see the mark in the book to face Tat)
(I will no longer use scanf/printf tat on POJ)
(POJ's title is the default for multiple sets of data, TAT)
Tips: Information Science Orsay Mathematics a pass of the standard and part of the code on the Baidu Access array out of bounds , face Black will GG (such as I qaq), detailed see
Test instructions: The number of numbers in the closed interval [A, a] is converted to binary after 0 is more than 1, 1<=a<b<=2* (10^9)
is obviously a digital DP routine: Solve (b+1)-solve (a) (the Solve (n) of the subject does not include N)
So the scope of our settlement becomes [0,n].
First turn n into binary (gray often obviously), throw into the array wt
Blue after we sort of discussion
1. Length of the <n length of the number to be evaluated
We can calculate the number of combinations directly.
Enumerates the lengths of the I=1 to Len-1-1 (the first bit must be 1 so one more button)
Re-enumeration of the number of 0 j= i/2+1 to I, accumulate C (i, j) it's over.
2. Length of the ==n length of the number to be evaluated
We take the WT array from high to low enumeration i= len-1 to 1 (∵↑↑∴len-1)
When wt[i]==0, we use the variable Z to count 0
When Wt[i]==1:
Let's first assume that this bit is 0, then the next few bits are strictly less than n, regardless of the rank
∴ can also enumerate the number of 0 in combination number blind
J= Max (0, (len+1)/2-(z+1)) to I-1
attention: Take Max to prevent the (negative) bounds of the array (the standard pot is here)
Finally, the answer is summed up, end.
Use 2h30min,6 submissions TAT
#include <iostream>using namespacestd;intMaxintAintb) {returnA>b?a:b;}intwt[ *],a,b,c[ *][ *];intSolveintN) { intres=0, z=0, len=0; for(; n;n>>=1) wt[++len]= (n&1); Turn Binary for(intI=1; i<len-1;++i)//length <n for(intj=i/2+1; j<=i;++j) Res+=C[i][j]; for(inti=len-1; i>=1;--i)//length ==nif(Wt[i]) { for(intJ=max (0, (len+1)/2-z-1); j<i;++j) Res+=c[i-1][j]; }Else++Z; returnRes;}intMain () { for(intI=0; i<= +;++i) for(intj=0; j<=i;++j) C[i][j]= (!j| | I==J)?1: c[i-1][j-1]+c[i-1][j]; while(cin>>a>>b) Cout<<solve (b +1)-solve (a) <<Endl; return 0;}
poj3252 Round Numbers