您的位置:首页 > 其它

POJ 3734 Blocks

2014-11-03 15:43 204 查看
矩阵快速幂的一个应用

本题要先将题意转化为递推式的形式

由第N块砖的染色方案推到第N+1块砖的染色方案数

ai:第i块砖时,红绿都是偶数的方案数

bi:红绿恰有一个为奇数的方案数

ci:红绿都是奇数的方案数

递推式:

a[i+1]=2*a[i]+b[i];
b[i+1]=2*a[i]+2*b[i]+2*c[i];
c[i+1]=b[i]+2*c[i];
由递推式得出递推矩阵

#include<stdio.h>
#include<vector>
using namespace std;
typedef vector<int> vec;
typedef vector<vec> mat;
const int M=10007;
//计算A*B
mat mul(mat &A,mat &B) {
mat C(A.size(), vec(B[0].size()));
int i,j,k;
for(i=0;i<A.size();i++) {
for(k=0;k<B.size();k++) {
for(j=0;j<B[0].size();j++) {
C[i][j]=( C[i][j]+ A[i][k]*B[k][j])%M;
}
}
}
return C;
}

//计算A^n
mat pow(mat A,int n) {
int i;
mat B(A.size(), vec(A.size()) );
for(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;
}
int n;

void solve() {
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);
printf("%d\n",A[0][0]);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int T;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: