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