USACO 3.2 Stringsobits
生活随笔
收集整理的這篇文章主要介紹了
USACO 3.2 Stringsobits
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
http://www.cppblog.com/yuziyu/archive/2009/07/03/89191.html
首先計算出組合數(shù)。用cmb_num[i][j]表示i位數(shù)中,"1的位數(shù)小于等于j"的數(shù)的個數(shù)。
這樣,我們從最左邊開始,如果cmb_num[i-1][j]的數(shù)大于n,說明第一位為0,因為用i-1位數(shù)中"1的位數(shù)小于等于j"的數(shù)已經(jīng)大于n個了。
如果小于n,說明第一位為1,需要i位,才能使"1的位數(shù)小于等于j"的數(shù)大于n個了。既然第一位已經(jīng)是1了,接下來的i-1位組成的數(shù)的1的個數(shù)只能小于等于n-1位了。迭代輸出每一位即可。
只是要注意溢出的問題以及cmb_num[0][1]。
#include <iostream> #include <fstream>using namespace std;ifstream fin("kimbits.in"); ofstream fout("kimbits.out");#ifdef _DEBUG #define out cout #define in cin #else #define out fout #define in fin #endifunsigned int cmb_num[32][32];void build_cmb_num() {for(int i=0;i<32;++i)cmb_num[i][0] = 1;for(int i=1;i<32;++i)for(int j=1;j<=i;++j)cmb_num[i][j] = cmb_num[i-1][j-1]+cmb_num[i-1][j];for(int i=0;i<32;++i)for(int j=1;j<32;++j){cmb_num[i][j]+=cmb_num[i][j-1];} }void solve() {build_cmb_num();unsigned n,l,i;in>>n>>l>>i;for(unsigned idx=n;idx>0;--idx){if( i> cmb_num[idx-1][l] ){out<<1;i-=cmb_num[idx-1][l];l--;}else{out<<0;} }out<<endl; }int main(int argc,char *argv[]) {solve(); return 0; }
總結
以上是生活随笔為你收集整理的USACO 3.2 Stringsobits的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。