现在的位置: 首页 > 综合 > 正文

骨牌覆盖

2013年10月18日 ⁄ 综合 ⁄ 共 1382字 ⁄ 字号 评论关闭

                                骨牌覆盖

     tale.pascal/c/cpp

 【题目描述】

给定一个2行n列的棋盘,用1*2的骨牌去完整覆盖,求方案数。

【输入】

输入仅包含一个数n。

【输出】

输出合法方案数模上1000000007。

【输入样例】

3

【输出样例】

3

 【样例解释】

000

000 表示一个长度为3,宽度为2的棋盘,有如下三种覆盖方式

 

112

332

 

123

123

 

122

133

 

1~3的数字分别表示三块不同骨牌的摆放

 注意:骨牌是不加以区分的,也就是说

112

332

113

223 被认为是同一种情况。

 

【数据规模】

对于20%的数据,n<5

对于所有数据,n<=100000

 解析:把n等于1,2,3,4,5,6,7的情况算出,依次是1,2,3,5,8,13,21,可以看出数列是遵循斐波那契数列规律的,可有如何证明呢?

我们用f[i]表示用i块骨牌有多少种情况,那么,可以根据最后一块骨牌的放置情况分类,当最后一块骨牌是竖直放置时,有f[i-1]种情况,1最后一块木块是横置时,倒数第二块木块也只能横置,所以有有f[i-2]种情况。综上:f[i]=f[i-1]+f[i-2],符合斐波那契数列规律,初始f[1]=1,f[2]=2.

代码见:

C++

#include<cstdio>

#include<cstdlib>

using namespacestd;

 

void init()

{

 freopen("tale.in","r",stdin);

 freopen("tale.out","w",stdout);

}

 

void work()

{

  int n,i,x,y,z;

  scanf("%d",&n);

  if(n==1){printf("%d\n",1);exit(0);}

  if(n==2){printf("%d\n",2);exit(0);}

 

  x=1;y=2;

  for(i=3;i<=n;i++)

    {

      z=(x+y)%1000000007;

      x=y;y=z;

    }

  printf("%d\n",z);

  //while(1); 

}

 

int main()

{

  init();

  work();

  return 0;

}

Pascal

 

 

procedure init;

begin

  assign(input,'tale.in');

  assign(output,'tale.out');

  reset(input);

  rewrite(output);

end;

 

procedure  terminate;

begin

  close(input);

  close(output);

  halt;

end;

 

procedure  main;

var

  n,i,x,y,z:longint;

begin

  read(n);

  if n=1 then

    begin

      writeln(1);

      termiante;

    end;

  if n=2 then

    begin

      writeln(2);

      terminate;

    end; 

   

  x:=1;y:=2;

  for i:=3 to n do

    begin

      z:=(x+y) mod 1000000007;

      x:=y; y:=z;

    end; 

  writeln(z); 

end;

 

begin

  init;

  main;

  terminate;

end.

抱歉!评论已关闭.