poj 3252 Round Numbers (楊輝三角求組合數)
阿新 • • 發佈:2018-11-16
題目連結:poj 3252
題意:給出範圍為 [a , b] 的區間,問在這區間內的每個數字,假如它的二進位制位0的個數大於1的個數,就說明它是Round Numbers,問你有多少個Round Numbers數?
題解:首先楊輝三角求組合數學,見程式碼。
///此題就是個組合數學題,二項式和為2^n, ///但這題卡我的是求組合數那裡,我剛想的是按一般方法求, ///但因為最多有32位,會爆,網上說用楊輝三角,一想是哦, ///做完這題又學會了用楊輝三角求組合數 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long LL; LL C[35][35]; int bits[35]; void init() ///楊輝三角求組合數 { C[0][0]=C[1][0]=C[1][1]=1; for(int i=2;i<33;i++) { C[i][0]=1; for(int j=1;j<i;j++) C[i][j]=C[i-1][j-1]+C[i-1][j]; C[i][i]=1; } } LL solve(int n) { if(n<=1) return 0; int len=0; while(n) { if(n&1) bits[++len]=1; else bits[++len]=0; n>>=1; } LL ans=0; ///當i為偶數時,說明在i-1位中,可以取C[i-1][i/2]+C[i-1][i/2+1]+...+C[i-1][i] ///當i為奇數時,說明在i-1位中,可以取C[i-1][i/2]+C[i-1][i/2+1]+...+C[i-1][i],比偶數多一個最中間的 for(int i=len-1;i>=2;i--) { if(i%2==0) ans+=((1<<(i-1)))/2; ///二項式和的一半 else ans+=((1<<(i-1))-C[i-1][(i-1)/2])/2; } int cnt1=0,cnt0=0; for(int i=1;i<=len;i++) { if(bits[i]==0) cnt0++; else cnt1++; } if(cnt0>=cnt1) ans++; ///本身就是 cnt0=0;cnt1=1; ///計數0 1 的個數 for(int i=len-1;i>=1;i--) { if(bits[i]==1){ ///後面有i-1位,我們把第i為看做0 for(int j=i-1;j>=0&&j+cnt0+1>=(i-1)-j+cnt1;j--) ///在i-1位中取j個0 ans+=C[i-1][j]; cnt1++; } else cnt0++; } return ans; } int main() { int a,b; init(); while(~scanf("%d%d",&a,&b)) { printf("%lld\n",solve(b)-solve(a-1)); } return 0; }