也算是组合 以前按组合做过一次 忘记怎么做的了
这次按dp写的 dp[i][j][g][k] 表示第i位为k(0|1)而且有j个1,g个0的情况数
貌似写的麻烦了。。。这一类的题,进行逐位计算就可以 不过要很细心,边界处理 特殊情况处理什么的 。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 100000 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 LL dp[35][35][35][2]; 18 int d[35]; 19 void init() 20 { 21 int i,j; 22 dp[1][0][1][0] = 1; 23 dp[1][1][0][1] = 1; 24 for(i = 2 ; i <= 32 ; i++) 25 for(j = 0; j <= i ; j++) 26 { 27 int k = i-j; 28 dp[i][j][k][0] += dp[i-1][j][k-1][0]+dp[i-1][j][k-1][1]; 29 dp[i][j][k][1] += dp[i-1][j-1][k][0]+dp[i-1][j-1][k][1]; 30 } 31 32 } 33 int judge(int x,int f) 34 { 35 int g=0,i,j,e; 36 while(x) 37 { 38 d[++g] = x%2; 39 x/=2; 40 } 41 42 int ans=0; 43 for(j = 1; j < g; j++) 44 for(i = 0 ; i <= j ;i++) 45 { 46 int k = j-i; 47 48 if(k>=i) 49 ans+=dp[j][i][k][1]; 50 } 51 int o = 0; 52 for(i = g-1 ; i >= 1 ; i--) 53 { 54 if(d[i+1]) o--; 55 else o++; 56 if(!d[i]) continue; 57 if(i==1) 58 { 59 o++; 60 if(o>=0) ans++; 61 continue; 62 } 63 for(e = 0 ; e <= i ; e++) 64 { 65 int k = i-e; 66 if(k-e+o>=0) 67 ans+=dp[i][e][k][0]; 68 } 69 } 70 if(f) 71 { 72 o = 0; 73 for(i = 1; i<= g ;i++) 74 if(d[i]) o--; 75 else o++; 76 if(o>=0) ans++; 77 } 78 return ans; 79 } 80 int main() 81 { 82 int a,b; 83 init(); 84 while(cin>>a>>b) 85 { 86 cout<<judge(b,1)-judge(a,0)<<endl; 87 } 88 return 0; 89 }