USACO Section 3.2 Stringsobits(dp)

Stringsobits
Kim Schrijvers

Consider an ordered set S of strings of N (1 <= N <= 31) bits. Bits, of course, are either 0 or 1.

This set of strings is interesting because it is ordered and contains all possible strings of length N that have L (1 <= L <= N) or fewer bits that are `1'.

Your task is to read a number I (1 <= I <= sizeof(S)) from the input and print the Ith element of the ordered set for N bits with no more than L bits that are `1'.

PROGRAM NAME: kimbits

INPUT FORMAT

A single line with three space separated integers: N, L, and I.

SAMPLE INPUT (file kimbits.in)

5 3 19

OUTPUT FORMAT

A single line containing the integer that represents the Ith element from the order set, as described.

SAMPLE OUTPUT (file kimbits.out)

10011
题意:一个长度为 N 的字符串,只含 0 和 1,组成一个集合 S。现在在 S 中留下字符串中 1 的个数小于等于 L 的字符串,按字典序排序输出第 I个字符串。
分析:
第一步:
d[i][j]表示长度为 i 的字符串,1 的个数小于等于 j。
d[i][j]=d[i-1][j-1]+d[i-1][j];d[i][0]=d[0][i]=d[0][0]=1; if j>i d[i][j]=d[i][i];
第二步:
这一步主要是求出第 I 个字符串。对于第 i 位如果d[i-1][L]<=I,则说明第 i 位是 1,否则就是 0。

View Code
/*
  ID: dizzy_l1
  LANG: C++
  TASK: kimbits
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 40

using namespace std;

long long d[MAXN][MAXN];

int main()
{
    freopen("kimbits.in","r",stdin);
    freopen("kimbits.out","w",stdout);
    long long N,L,I,i,j;
    while(cin>>N>>L>>I)
    {
        memset(d,0,sizeof(d));
        for(i=1;i<=N;i++) d[i][0]=1;
        for(i=0;i<=L;i++) d[0][i]=1;
        for(i=1;i<=N;i++)
        {
            for(j=1;j<=L;j++)
            {
                if(j>i)
                    d[i][j]=d[i][i];
                else
                    d[i][j]=d[i-1][j-1]+d[i-1][j];
            }
        }
        for(i=N; i>0; i--)
        {
            if (I!=1 && d[i-1][L]<I)
            {
                cout<<1;
                I-=d[i-1][L];
                L-=1;
            }
            else cout<<0;
        }
        cout<<endl;
    }
    return 0;
}

 



posted @ 2012-09-14 11:22  mtry  阅读(329)  评论(0)    收藏  举报