poj1953 World Cup Noise

http://poj.org/problem?id=1953

 

题目大意:给定一个正整数n,确定该长度的不同吟唱模式的数量,即确定不包含相邻1的n位序列的数目。例如,对于n = 3,答案是5 (序列000,001,010,100,101是可以接受的,而011,110,111不是)。输入第一行包含场景的数量。对于每个场景,在一行中,您将得到一个小于45的正整数。每个场景的输出从包含“Scenario #i:”的一行开始,其中i是从1开始的场景的数量。然后打印一行包含没有相邻1的n位序列的序列。用空行终止该场景的输出。

 

也就是说,给出一个数n,那么n位二进制数有2的n次方种不同的取值,我们要找出1不相邻的种数。当n=1时可取(0,1),f[1]=1,g[1]=1,fib[1]= f[1]+ g[1]=2,当n=2时可取(00,01,10),可见是在n=1的基础上在以0结尾的取值后面加0或1,在以1结尾的取值后面加0,f[2]=f[1]+g[1]=2,g[2]=f[1]=1,fib[2]=3

 

算法思想:递归算法,这里我们使用一次性计算的迭代法,改进算法的效率。设f[i]表示n=i时以0结尾的取值数,g[i]表示n=i时以1结尾的取值数,fib[i]表示n=i时的取值数。以0结尾可以在后面加0或1,以1结尾可以在后面加0,可以得到递归方程:

1)      f[i]=g[i-1]+f[i-1];  i>1

2)      g[i]=f[i-1];  i>1

3)      fib[i]=f[i]+g[i]; i>0

4)      f[1]=1;  i=1

5)      g[1]=1;  i=1

观察递归方程可以发现,这是一个斐波那契数列,(2,3,5,8,13…)

 

 1 #include <iostream>
 2 using namespace std;
 3 int main()
 4 {
 5     int fib[46];// 没有相邻的1的n位序列的序列数
 6     int f[46],g[46];
 7     f[1]=1;
 8     g[1]=1;
 9     fib[1]=f[1]+g[1];
10     for(int i=2;i<=45;i++)
11     {
12         f[i]=f[i-1]+g[i-1];
13         g[i]=f[i-1];
14         fib[i]=f[i]+g[i];
15     }
16     cin>>fib[0];//案例数
17     for(int i=1;i<=fib[0];i++)
18     {
19         int temp;
20         cin>>temp;
21         cout<<"Scenario #"<<i<<":\n"<<fib[temp]<<endl<<endl;
22     }
23     return 0;
24 }

猜你喜欢

转载自www.cnblogs.com/DA799422035/p/8995525.html