Covering
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 493 Accepted Submission(s): 230
To protect boys and girls from getting hurt when playing happily on the playground, rich boy Bob decided to cover the playground using his carpets.
Meanwhile, Bob is a mean boy, so he acquired that his carpets can not overlap one cell twice or more.
He has infinite carpets with sizes of 1×2 and 2×1 , and the size of the playground is 4×n .
Can you tell Bob the total number of schemes where the carpets can cover the playground completely without overlapping?
Each test case only contains one positive integer n in a line.
1≤n≤1018
1 2
1 5
这题对矩阵的构造操作也是骚的一逼
一开始真tmd傻逼推了前三项就得出递推公式,后来又推了几项才发现少考虑了很多种情况。。。
最后得出的递推式为f[n]=f[n-1]+4f[n-2]+3f[n-3]+2f[n-4]+3f[n-5] . . .
观察到奇数项和偶数项相加的系数等于5可以统一处理,所以用f[n]+f[n-1]=f[n-1]+4f[n-2]+2f[n-3]+3f[n-4]+2f[n-5] + f[n-2]+4f[n-3] +2f[n-4]+3f[n-5]...
——>f[n]= f[n-3]+ 5f[n-2]+5f[n-3]+5f[n-4]....
——>f[n]=f[n-3]+5sum(f[n-i])(i>=2);
然后就可以写出转移矩阵了
(f[n-1], sum[f[n-2]——>f[0]] ,f[n-3] ,[n-2])* (0,1,0,1)
(5,1,0,0)
(1,0,0,0)
(0,0,1,0)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
using namespace std;
typedef long long LL;
typedef vector<LL>a;
typedef vector<a>b;
const LL mod = 1000000007;
b jie(b m, b n)
{
b z(m.size(),a(n[0].size()));
for(int i=0; i<m.size(); i++)
{
for(int k=0; k<n.size(); k++)
{
for(int j=0; j<n[0].size(); j++)
{
z[i][j]=(z[i][j]+m[i][k]*n[k][j]%mod)%mod;
}
}
}
return z;
}
b Pow(b x,LL n)
{
b y(4,a(4));
for(int i=0; i<4; i++)
y[i][i]=1;
while(n>0)
{
if(n&1)
{
y=jie(y,x);
}
x=jie(x,x);
n>>=1;
}
return y;
}
int main()
{
LL n;
while(scanf("%lld",&n)!=EOF)
{
if(n==1) cout<<1<<endl;
else if(n==2) cout<<5<<endl;
else if(n==3) cout<<11<<endl;
else if(n==4) cout<<36<<endl;
else
{
b x(4,a(4));
x[0][0]=0,x[0][1]=1,x[0][2]=0,x[0][3]=1;
x[1][0]=5,x[1][1]=1,x[1][2]=0,x[1][3]=0;
x[2][0]=1,x[2][1]=0,x[2][2]=0,x[2][3]=0;
x[3][0]=0,x[3][1]=0,x[3][2]=1,x[3][3]=0;
x = Pow(x, n-4);
b y(1,a(4));
y[0][0]=36,y[0][1]=18,y[0][2]=5,y[0][3]=11;
y=jie(y,x);
printf("%lld\n",y[0][0]%mod);
}
}
return 0;
}