Tiling_easy version
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description
有一个大小是 2 x n 的网格,现在需要用2种规格的骨牌铺满,骨牌规格分别是 2 x 1 和 2 x 2,请计算一共有多少种铺设的方法。
Input
输入的第一行包含一个正整数T(T<=20),表示一共有 T组数据,接着是T行数据,每行包含一个正整数N(N<=30),表示网格的大小是2行N列。
Output
输出一共有多少种铺设的方法,每组数据的输出占一行。
Sample Input
3 2 8 12
Sample Output
3 171 2731
题意:有个2*n的教室,用2*1和2*2的砖块为该教室铺设地砖,问有多少种铺设方式
说实话,我是有点醉了,一份代码不用修改就可以AC两道题,赤裸裸地体现了一句话的精髓:万变不离其宗
来看看这道题,你就会知道我为什么会这么说了
HDU 2190 悼念512汶川大地震遇难同胞——重建希望小学(递推)
解题思路:这题说起来有点动态规划的意味,因为想知道n*2的教室有多少种铺设方式,无非考虑三种情况:
①如图橙色部分仅用1块2*1的砖块纵向铺设,这种情况对于2*(n-1)的教室的铺设方式种数是没有影响的,所以,该情况铺设的种数与2*(n-1)的教室的铺设方式种数是相等的,即s[n-1];
②如图橙色部分用1块2*2的砖块铺设,那么仅对蓝色部分会有影响,这种情况种数应为s[n-2];
③如图橙色部分用两块2*1的砖块横向铺设,这种情况同②,种数为s[n-2]
最终可得转移方程s[n]=s[n-1]+2*s[n-2]
n s[n]
1 1
2 3
3 5
4 11
5 21
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 31;
const int inf = 1000000000;
const int mod = 2009;
int s[N];
int main()
{
int t,i,n;
s[1]=1;s[2]=3;
for(i=3;i<N;i++)
s[i]=s[i-1]+2*s[i-2];
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("%d\n",s[n]);
}
return 0;
}
菜鸟成长记

探讨使用2x1和2x2规格的骨牌铺满2xN网格的方法数量,通过递推公式s[n]=s[n-1]+2*s[n-2]计算不同宽度网格的铺法总数。
1459

被折叠的 条评论
为什么被折叠?



