算法:递推+数学综合
题目大意:有t数据,给定一个2*n的矩阵,只能利用1*2和2*2的骨牌,让你去组成2*n的矩阵,问有多少种组成方法。
分析:从题目大意上不难看出,本题是一道递推题目,由前面的组成方案可以推得后面的组成方案,具体推法如下:
1:当前的2*n的矩阵可以拆分成2*(n-1)+1*2的或者是2*(n-2)+2*2的,所以组成2*i的矩形可以由以上两种方式组成,注意有重复。
2:如果读入的n是奇数,那么我们就少算了一种一个1*2的矩形在正中央,其它部分位于它左右的一种情况,这种情况下少算了一个矩形。
如果读入的n是偶数,那么就少算了两种情况,一个是把当前矩形平均分成两半的,这样的矩形由于之前已经算过一个了,所以只加上一个;还有一种情况就是当前矩形在减去一个1*2的矩形之后剩下的奇数长的矩形,而这样的组成方案又要按着刚才的算法计算。
题目大意:有t数据,给定一个2*n的矩阵,只能利用1*2和2*2的骨牌,让你去组成2*n的矩阵,问有多少种组成方法。
分析:从题目大意上不难看出,本题是一道递推题目,由前面的组成方案可以推得后面的组成方案,具体推法如下:
1:当前的2*n的矩阵可以拆分成2*(n-1)+1*2的或者是2*(n-2)+2*2的,所以组成2*i的矩形可以由以上两种方式组成,注意有重复。
2:如果读入的n是奇数,那么我们就少算了一种一个1*2的矩形在正中央,其它部分位于它左右的一种情况,这种情况下少算了一个矩形。
如果读入的n是偶数,那么就少算了两种情况,一个是把当前矩形平均分成两半的,这样的矩形由于之前已经算过一个了,所以只加上一个;还有一种情况就是当前矩形在减去一个1*2的矩形之后剩下的奇数长的矩形,而这样的组成方案又要按着刚才的算法计算。
3:最后注意之前算的都是在没考虑对称的情况下的结果,因此我们还要把结果除以2。
program D;
const
maxn=30;
var
f:array [0..maxn] of int64;
t,n:longint;
procedure main;
var
i,j:longint;
begin
f[0]:=1;
f[1]:=1;
readln(t);
for i:=1 to t do
begin
readln(n);
for j:=2 to n do f[j]:=f[j-1]+2*f[j-2];
if odd(n) then writeln((f[n]+f[(n-1) div 2]) div 2) else writeln((f[n]+2*f[(n div 2)-1]+f[n div 2]) div 2);
end;
end;
begin
assign(input,'D.in'); reset(input);
assign(output,'D.out'); rewrite(output);
main;
close(input); close(output);
end.