有N块砖块排成一列,从做往右开始染色,用 红,蓝,绿, 黄这四种颜色的油漆开始染色,求最后染色成功后红色和绿色的方块数都为偶数的方案的个数。
类似斐波那契数列的问题,考虑当染到n个方块时,有三种情况:红绿都是偶数个的方案为a,红绿有一个奇数的方案为b,红绿都为奇数的方案为c,
所以当染第i+1个方格的时候, a_=2a+b, b_=2a+2b+2c, c_=b+2c
所以利用类似斐波那契的矩阵算法,实现logn的复杂度。
题源来自《挑战程序竞赛》第二版 202页。
//
// 202_blocks (POJ 3734).cpp
// changlle
//
// Created by user on 1/28/16.
// Copyright (c) 2016 user. All rights reserved.
//
#include <iostream>
#include <vector>
using namespace std;
typedef vector<int> vec;
typedef vector<vec> mat;
typedef long long ll;
const int M=10007;
mat mul(mat& A, mat& B){
mat C(A.size(),vec(B[0].size()));
for (int i=0;i<A.size();i++)
for (int k=0;k<B.size();k++)
for (int j=0;j<B[0].size();j++)
C[i][j]=C[i][j]+A[i][k]*B[k][j];
return C;
}
mat pow (mat A, ll n ){
mat B(A.size(),vec(A[0].size()));
for (int i=0;i<A.size();i++)
B[i][i]=1;
while (n>0) {
if (n &1) B=mul(B,A);
A=mul(A,A);
n>>=1;
}
return B;
}
void solve() {
int n=2;
mat A(3,vec(3));
A[0][0]=2; A[0][1]=1; A[0][2]=0;
A[1][0]=2; A[1][1]=2; A[1][2]=2;
A[2][0]=0; A[2][1]=1; A[2][2]=2;
A=pow(A,n);
cout<<A[0][0]%M<<endl;
}
int main() {
solve();
return 0;
}