1031 骨牌覆盖(逆元再战)

在2*N的一个长方形方格中,用一个1*2的骨牌排满方格。
 
问有多少种不同的排列方法。
 
例如:2 * 3的方格,共有3种不同的排法。(由于方案的数量巨大,只输出 Mod 10^9 + 7 的结果)
Input
输入N(N <= 1000)
Output
输出数量 Mod 10^9 + 7
Input示例
3
Output示例

3

AC:代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define mod 1000000007
typedef long long ll;
ll fac[1005],vis[1005];
void init()
{
	fac[0] = 1;
	for(int i = 1;i<1001;i++){
		fac[i] = (fac[i-1]*i)%mod;
	}
}
ll ex_gcd(ll a,ll b,ll &x,ll &y){
	if(b == 0){
		x = 1;
		y = 0;
		return a;
	}
	ll temp = ex_gcd(b,a%b,y,x);
	y -= x*(a/b);
	return temp;
}
ll inv(ll s){
	ll x,y;
	ex_gcd(s,mod,x,y);
	return (x+mod)%mod;
}
int main()
{
	ios_base::sync_with_stdio(false); cin.tie(0);
	ll n;
	cin>>n;
	ll s = n/2;
	ll m;vis[0] = 1;
	init();
	for(int i = 1;i<=s;i++){
		m = n - i;
		vis[i] = (fac[m]%mod*inv(fac[m-i])%mod*inv(fac[i])%mod); 
	}
//	for(int i = 0;i<=s;i++){
//		printf("%lld ",vis[i]);
//	}printf("\n");
	ll ss = 0;
	for(int i = 0;i<=s;i++){
		ss += vis[i];
	}
	ss %= mod;
	printf("%lld\n",ss);
	return 0;
 } 
看了网上的博客,才知道可以用dp做
以下是转载

 

问题分析这是一个典型的递推计算题。

f(0) = 0,没有地方摆骨牌,所以为0;

f(1) = 1,只能竖着摆放1个骨牌;

f(2) = 2,可以是横着摆放2个骨牌,或者竖着摆放2个骨牌;

f(n) = f(n-2) + f(n-1),n>2,可以在f(n-2)的基础上在右边再横着放2个骨牌(竖着放已经在f(n-1)中),也可以在f(n-1)的基础上在右边再竖着1个骨牌。

#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
const int mod = 1000000007;
int main()
{
	int n;
	int f[1011];
	f[1] = 1;
	f[2] = 2;
	for (int i = 3 ; i <= 1000 ; i++)
		f[i] = (f[i-1] + f[i-2]) % mod;
	while (~scanf ("%d",&n))
		printf ("%d\n",f[n]);
	return 0;
}


posted @ 2018-04-28 17:06  Nlifea  阅读(109)  评论(0编辑  收藏  举报