POJ 3252 Round Numbers digital dp (getting started
Question:
Given an interval, calculate the number of valid values in the interval (when the number of values in the binary value is greater than or equal to 1, the value is legal. The binary value has no leading 0)
Ideas:
Cnt [I] indicates the number of valid numbers when the binary length is I bit (that is, the maximum bit is 1, and other digits are arbitrary.
Sum [I] is the valid number of BITs whose binary length is <= I.
Then, the data can be retrieved from the highest bit to the lowest Bit. Maintain the current number of zeros.
# Include
# Include
# Include
# Include
Template
Inline bool rd (T & ret) {char c; int sgn; if (c = getchar (), c = EOF) return 0; while (c! = '-' & (C <'0' | c> '9') c = getchar (); sgn = (c = '-')? -1: 1; ret = (c = '-')? 0: (c-'0'); while (c = getchar (), c> = '0' & c <= '9 ') ret = ret * 10 + (c-'0'); ret * = sgn; return 1;} template
Inline void pt (T x) {if (x <0) {putchar ('-'); x =-x;} if (x> 9) pt (x/10); putchar (x % 10 + '0');} using namespace std; typedef long ll; const int N = 100; int bit [N]; ll cnt [N], C [N] [N], sum [N]; ll dfs (int len) {ll ans = sum [len-1]; // The highest bit (I .e. the len bit must be 1) binary length <= valid number of len-1 int zero = bit [len] = 0; for (int I (len-1 ); i; I --) {if (bit [I] = 0) {zero ++; continue;} int tmp = zero + 1; // at this time, the I-th digit can be set to 0 or 1. If it is set to 0, the siz bit can be entered at will, and the number entered will not be greater than xint siz = I-1; if (tmp> = len-tmp) ans + = 1LL <siz; else {for (int j = 0; j <= siz; j ++) // enumerate the numbers of 0 similarly if (tmp + j> = len-tmp-j) ans + = C [siz] [j];} ans + = zero> = len-zero; // is the number of x LEGAL return ans;} ll solve (ll x) {if (x <= 1) return 1; int len = 0; for (ll tmp = x; tmp> = 1) bit [++ len] = tmp & 1; return dfs (len );} int main () {memset (C, 0, sizeof C); // calculates the number of combinations C [1] [0] = C [1] [1] = 1; for (int I = 2; I <N; I ++) {C [I] [0] = 1; for (int j = 1; j <N; j ++) C [I] [j] = C [I-1] [j] + C [I-1] [j-1];} cnt [1] = 1; sum [1] = 1; for (int I = 2; I <N; I ++) {cnt [I] = 0; // The binary length is I, the highest bit is 1, and the other bit is a valid number. for (int j = 0; j <= I-1; j ++) // because the highest bit is 1, so the number of free digits has a I-1, enumerate the number of 0 j, if the number of 0 j> = 1 number I-j, then the cnt [I] Method number + = select j 0if (j> = I-j) IN THE I-1 position) cnt [I] + = C [I-1] [j]; sum [I] = cnt [I] + sum [I-1];} long l, r; while (cin> l> r) cout <solve (r)-solve (l-1) <endl; return 0 ;}/ * 1 121 101 20 */