题意:用1x2或者2x1的地毯去铺满4xN的地面。给定N,问方案数.
(偶见DFS暴力搜索前10个结果,学习中,稍后贴上)
(偶见DFS暴力搜索前10个结果,学习中,稍后贴上)
解法:推导出公式后,转换成矩阵快速幂求解即可.
/*dfs暴力求解,便于找规律*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool book[7][1007];
int n, cnt;
bool findpos(int &x, int &y) {
for(int i=1 ; i<=4 ; i++) {
for(int j=1 ; j<=n ; j++) {
if(!book[i][j]) {
x = i, y = j;
return false;
}
}
}
return true;
}
void dfs(int x, int y) {
if(!book[x+1][y] && x<4) {
book[x][y] = book[x+1][y] = true;//纵向
int newx, newy;
if(findpos(newx, newy)) {//已经填满
book[x][y] = book[x+1][y] = false;//注销掉
cnt++;
return ;
}
dfs(newx, newy);//从未填满的地方开始继续dfs
book[x][y] = book[x+1][y] = false;//恢复
}
if(!book[x][y+1] && y<n) {//横向
book[x][y] = book[x][y+1] = true;
int newx, newy;
if(findpos(newx, newy)) {
book[x][y] = book[x][y+1] = false;
cnt++;
return ;
}
dfs(newx, newy);
book[x][y] = book[x][y+1] = false;
}
}
int main(){
while(~scanf("%d", &n)){
cnt=0;
dfs(1, 1);
cout << cnt<<endl;
}
}
/*
推导公式:F[i] = F[i-1] + 5*F[i-2] + F[i-3] - F[i-4]
*/
#include<bits/stdc++.h>
#define rep(i, a, b) for(int i=(a); i<(b); ++i)
using namespace std;
typedef long long ll;
const int maxn = 4;
const ll mod= 1e9+7;
struct Matrix{
ll tmp[maxn][maxn];
}a;
void init()
{
rep(i, 0, maxn){
rep(j, 0, maxn){
a.tmp[i][j]=0;
}
}
a.tmp[0][0]=a.tmp[0][2]=1;
a.tmp[0][1]=5;
a.tmp[0][3]=-1;
a.tmp[1][0]=a.tmp[2][1]=a.tmp[3][2]=1;
return;
}
Matrix mul(Matrix a,Matrix b)
{
Matrix ans;
rep(i, 0, maxn)
rep(j, 0, maxn){
ans.tmp[i][j]=0;
rep(k, 0, maxn){
ans.tmp[i][j]+=(a.tmp[i][k]*b.tmp[k][j]+mod)%mod;
ans.tmp[i][j]%=mod;
}
}
return ans;
}
void fun(Matrix ans,ll k)
{
rep(i,0,maxn){
rep(j, 0, maxn) {
a.tmp[i][j]=(i==j);
}
}
while(k){
if(k%2) a=mul(a,ans);
ans=mul(ans,ans);
k/=2;
}
return ;
}
int main(){
//freopen("in.txt", "r", stdin);
Matrix t;
ll n;
rep(i, 0, maxn){
rep(j, 0, maxn){
t.tmp[i][j]=0;
}
}
t.tmp[0][0]=36;
t.tmp[1][0]=11;
t.tmp[2][0]=5;
t.tmp[3][0]=1;
while(~scanf("%lld",&n))
{
init();
if(n<=4){
printf("%lld\n",t.tmp[4-n][0]);
continue;
}
fun(a,n-4);
a=mul(a,t);
printf("%lld\n",a.tmp[0][0]%mod);
}
return 0;
}