先暴力打表找规律:
#include <iostream>
using namespace std;
int xx, yy;
const int MAXN = 1000;
int visit[4][MAXN];
int ans;
int dis[2][2] = {1, 0, 0, 1};
void f(int n){
for(int i = 0; i < 4; ++i){
for(int j = 0; j < n; ++j){
if(visit[i][j] == 0) {
xx = i;
yy = j;
return ;
}
}
}
}
bool c(int n){
for(int i = 0; i < 4; ++i){
for(int j = 0; j < n; ++j){
if(visit[i][j] == 0){
return false;
}
}
}
return true;
}
void dfs(int x, int y, int n){
if(c(n)){
ans ++;
return;
}
if(visit[x][y] == 0){
for(int i = 0; i < 2; ++i){
int dx = x + dis[i][0];
int dy = y + dis[i][1];
if(dx < 4 && dy < n && visit[dx][dy] == 0){
visit[dx][dy] = 1;
visit[x][y] = 1;
f(n);
dfs(xx, yy, n);
visit[dx][dy] = 0;
visit[x][y] = 0;
}
}
}
}
int main(){
for(int i = 1; i <= 15; ++i){
ans = 0;
dfs(0, 0, i);
cout << ans << endl;
}
}
发现前8项分别为:
1 5 11 36 95 281 781 2245
找规律:
列方程组:
theta0 * f1 + theta1 * f2 + theta3 * f3 + theta4 * f4 = f5
theta1 * f2 + theta1 * f3 + theta3 * f4 + theta4 * f5 = f6
theta2 * f3 + theta1 * f4 + theta3 * f5 + theta4 * f6 = f7
theta3 * f4 + theta1 * f5 + theta3 * f6 + theta4 * f7 = f8
高斯消元:
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 4;
double theta[MAXN];
double a[MAXN][MAXN + 1];
void guass(int n){
memset(theta, 0, sizeof(theta));
for(int k = 1; k < n; ++k){
for(int i = k + 1; i <= n; ++i){
double l = a[i][k]/a[k][k];
for(int j = k + 1; j <= n + 1; ++j){
a[i][j] -= l*a[k][j];
}
}
}
for(int i = n; i >= 1; --i){
double b = a[i][n+1];
for(int j = i+1; j <= n; ++j){
b -= a[i][j]*theta[j];
}
theta[i] = b/a[i][i];
}
for(int i = 1; i <= n; ++i)printf("theta%d = %f\n", i, theta[i]);
}
int main(){
for(int i = 1; i <= 4; ++i)
for(int j = 1; j <= 5; ++j) cin >> a[i][j];
guass(4);
return 0;
}
得到结果:
theta0 = -1, theta1 = 1, theta2 = 5, theta3 = 1
所以递推式为:
F[n] = F[n-1] + 5F[n-2] + F[n-3] - F[n-4]
根据矩阵快速幂求解:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll MOD = 1000000007;
struct _Matrix{
int size;
ll matrix[10][10];
_Matrix(int _size){
size = _size;
}
_Matrix(){
size = 10;
}
void init0(){
memset(matrix, 0, sizeof(matrix));
}
void init1(){
memset(matrix, 0, sizeof(matrix));
for(int i = 0; i < size; ++i) matrix[i][i] = 1;
}
_Matrix Mutiple(_Matrix rhs){
_Matrix result(4);
for(int i = 0; i < size; ++i){
for(int j = 0; j < size; ++j){
result.matrix[i][j] = 0;
for(int k = 0; k < size; ++k){
result.matrix[i][j] += (rhs.matrix[i][k] * matrix[k][j] + MOD)%MOD;
result.matrix[i][j] %= MOD;
}
}
}
return result;
}
};
_Matrix qpow(_Matrix a, ll b){
_Matrix m(4);
m.init1();
while(b){
if(b&1) m = a.Mutiple(m);
a=a.Mutiple(a);
b >>= 1;
}
return m;
}
int main(){
_Matrix t(4);
t.init0();
t.matrix[0][0] = 1;
t.matrix[0][1] = 5;
t.matrix[0][2] = 1;
t.matrix[0][3] = -1;
t.matrix[1][0] = 1;
t.matrix[2][1] = 1;
t.matrix[3][2] = 1;
ll n;
while(cin >> n){
_Matrix ans(4);
if(n > 4){
ans = qpow(t, n-4l);
ll p = (ans.matrix[0][0]*36%MOD + ans.matrix[0][1]*11%MOD + ans.matrix[0][2]*5%MOD + ans.matrix[0][3]%MOD)%MOD;
cout << p << endl;
}else 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;
}
return 0;
}