usaco_3.2.2

求满足条件,且排列序为I的串。

有两种方式求,一是求出不满足条件的串,而所有串易求,不满足的也容易求,把不满足条件的串再I序前面的求出来,求出I的正常序。

2是直接统计满足条件按的串。

此题应为2的做法,因为不满足条件的串的求法和满足条件的串求法对称,也比较难求。

用dp[i][j]表示长度为i,1的个数不超过j的满足条件的串的个数。

那么dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1];

求出所有个数后,反向构造解。

现在要求为I的串,如果I是> dp[i - 1][j]的话说明第一个是1,否则的话说明第一个是0.

AC代码:

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

#include <cstdio>
#include <cstring>


const int MAX_NUMBER = 50;
long long dp[MAX_NUMBER][MAX_NUMBER];
long long n, l, order;
FILE *in, *out;

void printAns(long long cnt_order, int cnt_length, int one_number) {
    if (cnt_length <= 0) {
        return ;
    }
    if (cnt_order > dp[cnt_length - 1][one_number]) {
        fprintf(out, "1");
        printAns(cnt_order - dp[cnt_length - 1][one_number], cnt_length - 1, one_number - 1);
    }
    else {
        fprintf(out, "0");
        printAns(cnt_order, cnt_length - 1, one_number);
    }
}
int main() {
    in = fopen("kimbits.in", "r");
    out = fopen("kimbits.out", "w");
    memset(dp, 0, sizeof(dp));
    fscanf(in, "%lld%lld%lld", &n, &l, &order);
    for (int i = 0; i <= l; i++) {
        dp[0][i] = 1;
    }
    for (int i = 1; i <= n; i++) {
        dp[i][0] = 1;
        for (int j = 1; j <= l; j++) {
            dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1];
        }
    }
    printAns(order, n, l);
    fprintf(out, "\n");
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值