kimbits_USACO

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(N<=31)位二进制数。他们是排列好的,而且包含所有长度为N且这个二进制数中1的位数的个数小于等于L(L<=N)的数。你的任务是输出第i(1<=i<=长度为N的二进制数的个数)小的(注:题目这里表述不清,实际是,从最小的往大的数,数到第i个符合条件的,这个意思),长度为N,且1的位数的个数小于等于L的那个二进制数。(例:100101中,N=6,含有位数为1的个数为3)。

此题 I 最大值会爆int,= =

dp[i][j] 表示 i位的含j个1的二进制数个数,dp[i][j] = dp[i-1][j] + dp[i-1][j-1];

/*
ID: LinKArftc
PROG: kimbits
LANG: C++
*/

#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <utility>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define eps 1e-8
#define randin srand((unsigned int)time(NULL))
#define input freopen("input.txt","r",stdin)
#define debug(s) cout << "s = " << s << endl;
#define outstars cout << "*************" << endl;
const double PI = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int INF = 0x7fffffff;
typedef long long ll;

const int maxn = 35;

ll dp[maxn][maxn]; //dp[i][j]: i位的含j个1的二进制数个数
int n, l;
ll k;

void init() {
    dp[0][0] = dp[1][0] = dp[1][1] = 1;
    for (int i = 1; i < maxn; i ++) {
        dp[i][0] = 1;
        for (int j = 1; j < maxn; j ++) dp[i][j] = dp[i-1][j] + dp[i-1][j-1];
    }
}

int main() {
    freopen("kimbits.in", "r", stdin);
    freopen("kimbits.out", "w", stdout);
    init();
    scanf("%d %d %lld", &n, &l, &k);
    for (int i = 1; i <= n; i ++) {
        if (l == 0) {
            printf("0");
            continue;
        }
        ll sum = 0;
        for (int j = 0; j <= l; j ++) {
            sum += dp[n-i][j];
        }
        if (k <= sum) printf("0");
        else {
            printf("1");
            l --;
            k -= sum;
        }
    }
    printf("
");
    return 0;
}
原文地址:https://www.cnblogs.com/LinKArftc/p/5005999.html