洛谷 P2727 01串 Stringsobits
五年OI一场空,不开LongLong见祖宗
题意
你的任务是输出第i(1<=i<=长度为N的二进制数的个数)小的(注:题目这里表述不清,实际是,从最小的往大的数,数到第i个符合条件的,这个意思),长度为N,且1的位数的个数小于等于L的那个二进制数。
做法
数论加动态规划,f [ i ] [ j ] 存 前 i位 j 个 1 的数量,后面数论求第k个即可。详细请见代码。
代码
#include<bits/stdc++.h> using namespace std; long long n,l,k;//五年OI一场空,不开LongLong见祖宗 long long f[33][33]; int main() { //freopen("kimbits.in","r",stdin); //freopen("kimbits.out","w",stdout); scanf("%lld%lld%lld",&n,&l,&k); f[0][0]=1;//初始化 for(int i=1;i<=n;++i) { f[i][0]=1; for(int j=1;j<=l;++j) { f[i][j]=f[i-1][j-1]+f[i-1][j];//两种情况,一种是第 i 位是 1,另一种是第 i 位是 0 if(j>i) f[i][j]=0;//j>i 就说明不可能 if(j>i) f[i][j+1]=0; //动态规划 } } int s[33]; long long q=k; for(int i=n;i>=1;--i) { long long sum=0; for(int j=0;j<=l;++j) sum+=f[i-1][j]; if(sum<q) q-=sum,s[i]=1,--l; else s[i]=0; //数论求解 } for(int i=n;i>=1;--i) printf("%d",s[i]);//倒序输出 printf("\n"); return 0; }

浙公网安备 33010602011771号