在2*N的一个长方形方格中,用一个1*2的骨牌排满方格。
问有多少种不同的排列方法。
例如:2 * 3的方格,共有3种不同的排法。(由于方案的数量巨大,只输出 Mod 10^9 + 7 的结果)
![](http://img.51nod.com/upload/000fb99c/08cfb32da97093cc00000644.jpeg)
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("
");
ll ss = 0;
for(int i = 0;i<=s;i++){
ss += vis[i];
}
ss %= mod;
printf("%lld
",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
",f[n]);
return 0;
}