关闭

usaco_3.2.2

376人阅读 评论(0) 收藏 举报
分类:

求满足条件,且排列序为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;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:86968次
    • 积分:1930
    • 等级:
    • 排名:千里之外
    • 原创:106篇
    • 转载:2篇
    • 译文:0篇
    • 评论:11条
    阅读排行
    最新评论