标签:usaco 动态规划 算法 c stringsobits
Stringsobits
Kim SchrijversConsider 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 andcontains 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 Nbits with no more than L bits that are `1‘.
5 3 19
10011
分析
分3步进行
1.c[i][j]为位数为i,含有1的个数为j的二进制数的个数。其实c[i][j]就是组合数,这个数组就是杨辉三角。初始化后迭代求解这个数组。
2.c[i][j]现在为位数为i,含有1的个数小于等于j的二进制数的个数。叠加。
3.求解第I小的二进制数:从高到低依次求出每一位
总结:题目中的“第I大”应该是第I小,另外注意I值用int越界问题,用unsigned int即可。
通过代码
/* ID: c1033311 LANG: C++ TASK: kimbits */ #include<stdio.h> int main(){ FILE *fin=fopen("kimbits.in","r"); FILE *fout=fopen("kimbits.out","w"); unsigned int N,L,I; unsigned int c[32][32]; //c[i][j]为位数为i,含有1的个数为j的二进制数的个数 unsigned int i,j; fscanf(fin,"%u%u%u",&N,&L,&I); //初始化c[i][j] for(i=0;i<=N;++i) { c[i][0]=1; //全0 c[i][i]=1; //全1 } //迭代求解c[i][j] for(i=2;i<=N;++i) for(j=1;j<=L&&j<i;++j) c[i][j]=c[i-1][j]+c[i-1][j-1]; //c[i][j]现在为位数为i,含有1的个数小于等于j的二进制数的个数 for(i=1;i<=N;++i) for(j=1;j<=L&&j<=i;++j) c[i][j]+=c[i][j-1]; //求解第I小的二进制数:从高到低依次求出每一位 unsigned int sum=0; //目前为止满足要求的二进制数个数 unsigned int n1=0; //目前为止用掉1的个数 for(i=1;i<=N;++i) { unsigned int tmp=L-n1; if(tmp>N-i) tmp=N-i; if(c[N-i][tmp]+sum==I-1) { fprintf(fout,"1"); for(j=i+1;j<=N;++j) fprintf(fout,"0"); break; } else if(c[N-i][tmp]+sum<I-1) { fprintf(fout,"1"); sum+=c[N-i][tmp]; n1++; } else fprintf(fout,"0"); } fprintf(fout,"\n"); return 0; }
标签:usaco 动态规划 算法 c stringsobits
原文地址:http://blog.csdn.net/hiboy_111/article/details/43851791