poj 3252 Round Numbers
题目链接:http://poj.org/problem?id=3252
题意:给出一个二进制区间,求出0的个数不小于1的个数这样的二进制个数
解法:数位DP,定义状态dp[len][num_zero][num_one],num_zero 定义为写0的个数。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #define inf 0x7fffffff 8 #define exp 1e-10 9 #define PI 3.141592654 10 using namespace std; 11 typedef long long LL; 12 LL digit[35]; 13 LL dp[35][35][35]; 14 LL dfs(LL len,LL num_zero,LL num_one,bool fp,int flag) 15 { 16 if (!len) 17 { 18 if (flag && num_zero>=num_one) return 1; 19 return 0; 20 } 21 if (!fp && dp[len][num_zero][num_one]!=-1) 22 return dp[len][num_zero][num_one]; 23 LL ret=0; 24 LL fpmax= fp ? digit[len] : 1; 25 for (LL i=0 ;i<=fpmax ;i++) 26 { 27 LL s= i==1 ? 1 : 0; 28 LL s2= flag && i==0 ? 1 : 0; 29 ret += dfs(len-1,num_zero+s2,num_one+s,fp && i==fpmax,flag || i==1); 30 } 31 if (!fp) return dp[len][num_zero][num_one]=ret; 32 return ret; 33 } 34 LL f(LL n) 35 { 36 LL len=0; 37 while (n) 38 { 39 digit[++len]=n%2; 40 n /= 2; 41 } 42 return dfs(len,0,0,true,0); 43 } 44 int main() 45 { 46 LL a,b; 47 while (cin>>a>>b) 48 { 49 memset(dp,-1,sizeof(dp)); 50 printf("%I64d\n",f(b)-f(a-1)); 51 } 52 return 0; 53 }