1265. Round Numbers(rndnum.pas/c/cpp)
(File IO): input:rndnum.in output:rndnum.out
Time Limits: 1000 ms Memory Limits: 65536 KB Detailed Limits
Goto ProblemSet做法:跑一边数位dp,设f[i][j]表示i位2进制数中有j个1的方案数,f[i][j] = f[i - 1][j - 1] + f[i - 1][j]; 然后统计答案;
代码如下:
View Code
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <string> 5 using namespace std; 6 int a, b; 7 int f[40][40], s[40]; 8 9 void pre_work() 10 { 11 f[0][0] = 1; 12 for (int i = 1; i <= 35; i++) 13 f[i][0] = 1; 14 for (int i = 1; i <= 35; i++) 15 for (int j = 1; j <= i; j++) 16 f[i][j] = f[i - 1][j - 1] + f[i - 1][j]; 17 } 18 19 int work(int x) 20 { 21 if (!x) return 0; 22 int m = 0, ans = 0, sum = 1; 23 while (x) 24 { 25 s[++m] = x & 1; 26 x >>= 1; 27 } 28 for (int i = 2; i < m; i++) 29 for (int j = 0; j < i / 2; j++) 30 ans += f[i - 1][j]; 31 for (int i = m - 1; i; i--) 32 { 33 if (s[i]) 34 { 35 for (int j = 0; j <= m / 2 - sum; j++) 36 ans += f[i - 1][j]; 37 } 38 sum += s[i]; 39 } 40 ans += sum <= (m / 2); 41 return ans; 42 } 43 44 int main() 45 { 46 freopen("rndnum.in", "r", stdin); 47 freopen("rndnum.out", "w", stdout); 48 scanf("%d%d", &a, &b); 49 pre_work(); 50 cout << work(b) - work(a - 1); 51 }