设长度为j的01串,1的个数不大于k的个数为f[j,k]
方程:f[j,k]=f[j-1,k]+f[j-1,k-1]; //分别表示在当前位加上0和加上1时的两种状况
边界:f[j,0]=1,f[0,j]=1;f[j,k](k>j)=f[j,j]
这样我们得到了所有的f[j,k](),需要做的就是据此构造出所求字符串.
设所求串为S,假设S的位中最高位的1在自右向左第K+1位,那么必然满足F[K,L]< I,F[K+1,L] >=I,这样的K是唯一的。所以S的第一个1在从右至左第K+1位.因为有F[K,L]个串第K+1位上为0,所以所求的第I个数的后K位就应该是满足"位数为K且串中1不超过L-1个"这个条件的第I-F[K,L]个数。
于是我们得到这样的算法:
S:='00....0'(n个0)
for K:=n-1 downto 0 do {题目保证有解,所以f[N,L]>I}
if F[K,L]<I then
begin
s[N-K]:=1;
dec(I,F[K,L]);{第K+1位是1,所以I减去第K+1位是0的串的个数}
dec(L);
end;
如果I>=F[k,l],说明第k+1位为1,又因为有F[k,l]个数的第k+1位为‘0’,则这个数满足第k+1位为1,且满足“是第I-f[k,l]个后面k位里至多含有l-1个1”
如果I<F[k,l],说明第k+1位为0,则这个数满足第k+1位为0,则与F[k-1,l]比较。