Problem Description
给你一个4×N的矩阵,你可以填1×2的矩阵或者2×1的矩阵,填满有多少种方案,需要取mod。
思路
POJ - 3420 和这题可以说是一种题,但是代码使用在这题上面超时,很不能理解,后面学习了网上的做法,先找出递推关系,在矩阵快速幂,别人的速度能在1000ms以内,我的居然2000ms。有知道的大佬可以指出为什么。
//ac代码,为什么会跑到2000ms不能理解
#include<cstdio>
#include<cstring>
using namespace std;
#define mod 1000000007
struct node
{
long long a[4][4];
};
long long n;
node res, ans;
void init()//初始化
{
res.a[0][0] = 36;
res.a[1][0] = 11;
res.a[2][0] = 5;
res.a[3][0] = 1;
memset(ans.a, 0, sizeof(ans.a));
ans.a[0][0] = 1;
ans.a[0][1] = 5;
ans.a[0][2] = 1;
ans.a[0][3] = -1;
ans.a[1][0] = ans.a[2][1] = ans.a[3][2] = 1;
}
node mul(node x, node y)//矩阵相乘
{
int i, j, k;
node sum;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
sum.a[i][j] = 0;
for(k = 0; k < 4; k++)
{
sum.a[i][j] += ((x.a[i][k] + mod) % mod * (y.a[k][j] + mod) % mod) % mod;
sum.a[i][j] += mod;
sum.a[i][j] %= mod;
}
}
}
return sum;
}
node Pow(node t, long long m)//矩阵快速幂
{
node sum;
int i;
memset(sum.a,0,sizeof(sum.a));
for (i=0;i<4;i++)
sum.a[i][i]=1;
while(m)
{
if(m & 1) sum = mul(sum, t);
t = mul(t, t);
m >>= 1;
}
return sum;
}
int main()
{
init();
node temp;
while(~scanf("%lld", &n))
{
if(n <= 4)
{
printf("%lld\n", res.a[4 - n][0]);
continue;
}
temp = Pow(ans, n - 4);
temp = mul(temp, res);
printf("%lld\n", temp.a[0][0]);
}
return 0;
}
//超时代码
#include<cstdio>
#include<cstring>
using namespace std;
#define mod 1000000007
struct node
{
long long a[16][16];
};
node c;
long long n;
void dfs(int l, int now, int pre)
{
if(l > 4) return;
if(l == 4)
{
c.a[pre][now]++;
return ;
}
dfs(l + 2, (now<<2)|3, (pre<<2)|3);
dfs(l + 1, now<<1, (pre<<1)|1);
dfs(l + 1, (now<<1)|1, pre<<1);
}
node mul(node x, node y)
{
node ans;
int i, j, k;
for(i = 0; i < 16; i++)
{
for(j = 0; j < 16; j++)
{
ans.a[i][j] = 0;
for(k = 0; k < 16; k++)
{
ans.a[i][j] += x.a[i][k] * y.a[j][k];
ans.a[i][j] %= mod;
}
}
}
return ans;
}
node sm(node x, long long m)
{
node ans;
memset(ans.a, 0, sizeof(ans.a));
for(int i = 0; i < 16; i++) ans.a[i][i] = 1;
while(m)
{
if(m & 1) ans = mul(ans, x);
x = mul(x, x);
m = m>>1;
}
return ans;
}
int main()
{
memset(c.a, 0, sizeof(c.a));
dfs(0, 0, 0);
while(~scanf("%lld", &n))
{
node ans = sm(c, n);
printf("%lld\n", ans.a[15][15]);
}
return 0;
}