poj 3252 Round Numbers
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 3252 Round Numbers相关的知识,希望对你有一定的参考价值。
题目链接:http://poj.org/problem?id=3252
题意:如果一个数的二进制表示中它的0的个数大于或等于1的个数,那么这是一个Round Numbers。
给出一个区间,问这个区间中共有多少个Round Numbers。
思路:
记忆化搜索,判断最后的数的0和1的个数,但是要注意前导0的情况,要把前导0的个数去掉。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 int num[40]; 6 int dp[40][2][40][40]; 7 int dfs(int cur, int allzero, int one, int zero, int limit) 8 { 9 if(cur < 0) 10 { 11 if(!allzero && (zero >= one)) return 1; 12 else return 0; 13 } 14 if(!limit && dp[cur][allzero][one][zero] != -1) return dp[cur][allzero][one][zero]; 15 16 int ret = 0; 17 int up = limit?num[cur]:1; 18 for(int i = 0; i <= up; i++) 19 { 20 if(i == 0 && allzero == 0) ret += dfs(cur-1, allzero, one, zero+1, limit && i == up); 21 else if(i == 0 && allzero == 1) ret += dfs(cur-1, allzero, 0, 0, limit && i == up); 22 else if(i == 1 && allzero == 0) ret += dfs(cur-1, allzero, one+1, zero, limit && i == up); 23 else if(i == 1 && allzero == 1) ret += dfs(cur-1, 0, one+1, zero, limit && i == up); 24 } 25 if(!limit) dp[cur][allzero][one][zero] = ret; 26 return ret; 27 } 28 int slove(int x) 29 { 30 memset(dp, -1, sizeof(dp)); 31 int cnt = 0; 32 while(x) 33 { 34 num[cnt++] = x%2; 35 x /= 2; 36 } 37 return dfs(cnt-1, 1, 0, 0, 1); 38 39 } 40 int main() 41 { 42 // freopen("in.txt", "r", stdin); 43 // freopen("out.txt", "w", stdout); 44 int n, m; 45 while(~scanf("%d%d", &n, &m)) 46 { 47 printf("%d\n", slove(m) - slove(n-1)); 48 } 49 return 0; 50 }
以上是关于poj 3252 Round Numbers的主要内容,如果未能解决你的问题,请参考以下文章