时间:2021-07-01 10:21:17 帮助过:30人阅读
很快就发现了这题的递推特性。简直是赤裸裸啊~ 定义一个数组( [串长度][串中'1'的个数]=种类数 )这就是一个排列啊~ 用一个简单的递推方程求解出来C(n,i)=C(n-1,i)C(n-1,i-1); 然后从首位n开始判断,∑C[n-1][i] ( i∈[0,l] ) 若和大于等于当前的第k个数则说明
很快就发现了这题的递推特性。简直是赤裸裸啊~
定义一个数组( [串长度][串中'1'的个数]=种类数 )这就是一个排列啊~
用一个简单的递推方程求解出来C(n,i)=C(n-1,i)+C(n-1,i-1);
然后从首位n开始判断,∑C[n-1][i] ( i∈[0,l] )
若和大于等于当前的第k个数则说明,右边的n-1位足够提供题中所需的数量,因此当前位为'0';
若右边n-1位不能提供所需的数量,则当前位为'1',右边必须向n借一位,这样k-=cnt;把右边的和减去。提供的l--;
蛮有意思的一题:
Code:
/* ID:bysen LANG:C++ PROG:kimbits */ #includeusing namespace std; int C[32][32]; int main() { freopen( "kimbits.in","r",stdin ); freopen( "kimbits.out","w",stdout ); int n,l; long long k; scanf( "%d %d %lld",&n,&l,&k ); for( int i=0;i<32;i++ ) for( int j=0;j<32;j++ ) C[i][j]=0; for( int i=0;i<32;i++ ) C[i][0]=1; for( int i=1;i<32;i++ ) for( int j=1;j<32;j++ ) C[j][i]=C[j-1][i]+C[j-1][i-1]; for( int i=n;i>=1;i-- ) { int cnt=0; for( int j=0;j<=l;j++ ) cnt+=C[i-1][j]; if( cnt