【算法】【动态规划】Domino Tiling

问题描述:

A domino means a shape in which sides of two unit rectangles are put together to each other.

Domino tilting means to make a mosaic by filling a certain area of a flat plate with dominoes, leaving no empty space.

You are going to put 2x1 or 2x2 dominoes into an 2×N rectangle-shaped frame.

Find the number of cases of how dominoes can be put into.

Since the number of cases is too many, output the remainder after dividing by a given number M.


The following figure is an example of domino tiling in an 2x8 frame.


Time limit : 2 second (Java : 4 sec)


[Input]

There can be more than one test case in the input file. The first line has T, the number of test cases.
Then the totally T test cases are provided in the following lines (T ≤ 10)
In each test case, the first line has an integer N(1 ≤ N ≤ 100,000), the length of the width of the rectangle frame.
The next line, a number M (1 ≤ M ≤ 40000) is given for the mod operation.


[Output]
In the each line, output the remainder found after dividing the number of cases by.


[I/OExample]

Input
1
8
100


Output

71

分析:

动态规划, N的可能性只和N-1和N-2有关系,如果上一个是N-2,则剩下的2×2可能的组合是三种(2×2, 两个2×1, 两个1×2),如果上一种是N-1, 则只有一种可能性,(一个2×1),但是这种可能性已经被包含到N-2中,所以要剔除N-2中的一个可能性,所以N的组合是有2× (N-2)的可能性 + 1×(N-1)的可能性

源码:

#include <cstdio>
#include <iostream>

using namespace std;

int N,M;
int Answer;

int main(int argc, char** argv)
{
	int test_case;
	int T;
	int s1;
	int s2;
	int s3;
	/*
	   The freopen function below opens input.txt file in read only mode, and afterward,
	   the program will read from input.txt file instead of standard(keyboard) input.
	   To test your program, you may save input data in input.txt file,
	   and use freopen function to read from the file when using cin function.
	   You may remove the comment symbols(//) in the below statement and use it.
	   Use #include<cstdio> or #include<stdio.h> to use the function in your program.
	   But before submission, you must remove the freopen function or rewrite comment symbols(//).
	*/
	// freopen("input.txt", "r", stdin);

	cin >> T;
	for(test_case = 0; test_case < T; test_case++)
	{
		cin >> N;
		cin >> M;
		
		/**********************************
		*  Implement your algorithm here. *
		***********************************/
		Answer = 0;

		if (N == 1) 
			Answer = 1 % M;
		else if (N == 2) 
			Answer = 3 % M;
		else
		{
			s1 = 1;
			s2 = 3;
			int i;

			for (i = 2; i < N; i++)
			{
				s3 = (s2 + 2 * s1) % M;
				s1 = s2;
				s2 = s3;
			}
			Answer = s3;
		}
		// Print the answer to standard output(screen).
		cout << Answer << endl;
	}

	return 0;//Your program should return 0 on normal termination.
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值