递归递推 URAL1081 递归

1081. Binary Lexicographic Sequence

Time limit: 0.5 second
Memory limit: 64 MB

Consider all the sequences with length (0 < N < 44), containing only the elements 0 and 1, and no two ones are adjacent (110 is not a valid sequence of length 3, 0101 is a valid sequence of length 4). Write a program which finds the sequence, which is on K-th place (0 < K < 109) in the lexicographically sorted in ascending order collection of the described sequences.

Input

The first line of input contains two positive integers N and K.

Output

Write the found sequence or −1 if the number K is larger then the number of valid sequences.

Sample

input output
3 1 000

 

首先可以递推出来,每增加一个长度/一个字符,至当前长度n

if (0)

  f(n) += f(n-1);  //前面n-1长度的字符串的合法个数

else (1)

  f(n) += f(n-2); 

//如果是1,第n-1个字符一定是0,所以加上前面n-2长度字符串的合法个数

所以递推式是 f(n) = f(n-1) + f(n-2)

而后我们有了一个n长度字符串第k种的问询

根据刚才的递推,我们可以知道,f(n)第一位是0时,有f(n-1)个,

所以 ,可以根据kf(n-1)的大小关系,我们可以知道第一位是0还是1

if(k>f(len-1)){

  输出1   , 并把k减小为k-f(len-1)

else{

  输出0   , 

}

继续下一层的问询

以此类推,每次都可以得出第一位的字符并输出

 

#include 

const int maxn=44;

int n;
long k;
long num[maxn+10];

void f(long long k,int len)
{
	if(len<=0)	return;
	if(k>0){
		if(k>num[len-1]){
			printf("1");
			f(k-num[len-1],len-1);	//除去开头1的再考虑
		}
		else{
			printf("0");
			f(k,len-1);
		}
	}
}

int main()
{
	num[0]=1;num[1]=2;num[2]=3;
	scanf("%d%ld",&n,&k);
	for(int i=3;i<=n;++i){
		num[i]=num[i-1]+num[i-2];	//分是0是1两种情况考虑
	}
	if(k<1||k>num[n]){
		printf("-1\n");
		return 0;
	}
	f(k,n);

	return 0;
}

 

你可能感兴趣的:(ACM,递归递推)