HDU 1992 Tiling a Grid With Dominoes (状压 dp)

Problem Description

We wish to tile a grid 4 units high and N units long with rectangles (dominoes) 2 units by one unit (in either orientation). For example, the figure shows the five different ways that a grid 4 units high and 2 units wide may be tiled.

Write a program that takes as input the width, W, of the grid and outputs the number of different ways to tile a 4-by-W grid.

Input

The first line of input contains a single integer N, (1 ≤ N ≤ 1000) which is the number of datasets that follow.

Each dataset contains a single decimal integer, the width, W, of the grid for this problem instance.

Output

For each problem instance, there is one line of output: The problem instance number as a decimal integer (start counting at one), a single space and the number of tilings of a 4-by-W grid. The values of W will be chosen so the count
will fit in a 32-bit integer.

Sample Input

3
2
3
7

Sample Output

1 5
2 11
3 781

一个地点为 1 代表是放着竖着向下的砖

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>

#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)

#define eps 1e-8

#define fre(i,a,b)  for(i = a; i <b; i++)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define bug         pf("Hi\n")

using namespace std;

#define INF 0x3f3f3f3f
#define N 22

int dp[N][16];

void dfs(int dep,int up,int down,int pos)     //第 dep行状态为 up 更新下一行状态为 down 的情况
{
	if(pos>3)
	{
		dp[dep+1][down]+=dp[dep][up];
		return ;
	}

	if(up&(1<<pos))                       //上一行对下一行的pos位置填满
	{
		 dfs(dep,up,down,pos+1);
	     return ;
	}

	dfs(dep,up,down|(1<<pos),pos+1);      //竖着放在dep+1层的pos位置一个竖着向下的砖
	if(pos<=2&&!(up&(1<<(pos+1))))        //横着放一块砖,占据两个位置
		 dfs(dep,up,down,pos+2);

}

int main()
{
	int i,j,t,ca=0;
	dp[0][0]=1;

	fre(i,0,N)
	 fre(j,0,16)
	   if(dp[i][j])
		 dfs(i,j,0,0);

	sf(t);
	while(t--)
	{
		sf(i);
		pf("%d %d\n",++ca,dp[i][0]);
	}
	return 0;
}
时间: 2024-10-29 23:18:00

HDU 1992 Tiling a Grid With Dominoes (状压 dp)的相关文章

zoj zju 2994 Tiling a Grid With Dominoes 状压dp

Tiling a Grid With Dominoes Time Limit: 2 Seconds      Memory Limit: 65536 KB We wish to tile a grid 4 units high and N units long with rectangles (dominoes) 2 units by one unit (in either orientation). For example, the figure shows the five differen

ZOJ 2994 &amp;&amp; HDU 1992 Tiling a Grid With Dominoes (状压DP)

题目链接:HDU 1992 Tiling a Grid With Dominoes 题意:一个4*N的矩形,用1*2的小矩形铺满的方法数是多少. 思路:4*N.只有4行想到状压,dp[i][j]表示前i行状态j的方法数,影响当前行的只有上一行!0成对出现表示横着放,1表示竖着放,所以第一行的状态0.3.9.12.15五种,并且只要上一行是0状态.当前行的状态就为0.3.9.12.15五种可能.还有当前行s1和上一行s2匹配仅当s1==0 || s1==(s2取反),特别注意上一行状态是0110(

hdu 5135 Little Zu Chongzhi&#39;s Triangles 状压DP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5135 从大到小贪心是不对的! 比如 4 30 40 50 89 这组数据 结果应该是600 如果取后三条边只会是一个细长细长的三角形根本没多大面积 只不过因为数据水然后贪心碰巧能过而已 看到网上题解很多人用贪心我好郁闷... 状压DP 看到边的数目很少就应该想到这个了 先枚举可能出现的所有三角形 记录他们使用了那些边还有他们的面积 然后再枚举状态之中 套一层遍历所有三角形的循环 如果当前状态和三角形

HDU 5131 Little Zu Chongzhi&#39;s Triangles (状压DP +2014广州现场赛)

题目链接:HDU 5131 Little Zu Chongzhi's Triangles 题意:给出一些线段,在其中选出3根组成三角形,问用这些线段组成的所有三角形的最大面积是多少. 7 3 4 5 3 4 5 90 两个三角形是(3,3,4),(5,5,4). 思路:N最大12,状态压缩,把所有可能组成的三角形存起来.A&B==0则说明A|B状态是有效的. 贪心也能过..为什么? AC代码: #include <stdio.h> #include <string.h> #

HDU 3920Clear All of Them I(状压DP)

HDU 3920   Clear All of Them I 题目是说有2n个敌人,现在可以发n枚炮弹,每枚炮弹可以(可以且仅可以)打两个敌人,每一枚炮弹的花费等于它所行进的距离,现在要消灭所有的敌人,问最少花费是多少(反正题意大概就是这样啦,知道怎么回事就好了,解释不清了) 一看到n<=10而且又是在DP专题里的,就知道这个显然是状压DP,由于有2n个敌人,所以状态表示由当前状态再打两个人来转移, 10000100表示打了这两个敌人的最小花费 所以状态的转移是由前往后递推的,假如当前状态是cu

HDU 5135 Little Zu Chongzhi&#39;s Triangles(状压dp或者贪心)

题目大意:给你n个线段让你任意组成三角形,求组出来的三角形的面积的和最大为多少. 解题思路:首先你得知道海伦公式:S = sqrt(p*(p-a)*(p-b)*(p-c)), p = (a+b+c)/2. 思路一:贪心,按照边的长度进行排序,从大到小判断如果可以构成三角形,就让他构成三角形,这样组成的三角形的面积和一定是最大的. 思路二:状压dp,先暴力求出来所有可以组成的三角形对应的状态和面积,然后dp求解,状态转移公式是:dp[i|(f[j].xnum)] = max(dp[i|(f[j].

HDU 3681 Prison Break(bfs+二分+状压DP)

Prison Break Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3778    Accepted Submission(s): 992 Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But on

HDU 5067 Harry And Dig Machine(状压dp)

HDU 5067 Harry And Dig Machine 思路:由于点才10个,在加上一个起点,处理出每个点之间的曼哈顿距离,然后用状压dp搞,状态表示为: dp[i][s],表示在i位置,走过的点集合为s的最小代价 代码: #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int N = 15;

HDU 1565 方格取数(1)(状压DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1565 Problem Description 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大. Input 包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20) Output 对于每个测试实例,输出可能取得的最大的和 Sample Input 3 75