Blocks POJ - 3734
打表可得规律 an=3an-1 +bn-1 bn=4bn-1 +2^(n-1)
dp也可,设a00 a01 a02 分别为红绿均偶 红绿一奇一偶 红绿均奇 转移矩阵快速幂
组合数学可用总方案4^n - 不符合条件的方案数 = 4^(n-1)+2^(n-1)
我找了规律。。。感觉自己low了好多。。
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int MOD=10007; const int sz=4; int n=3; struct mat{ int a[sz][sz]; mat(){memset(a,0,sizeof a);} void initE(){for(int i=0;i<n;i++)a[i][i]=1;} void initfib(){a[1][0]=a[0][1]=a[0][0]=1;a[1][1]=0;} mat operator*(const mat&t)const{ mat q; for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) q.a[i][j]=(q.a[i][j]+a[i][k]*t.a[k][j])%MOD; return q; } void out(){ for(int i=0;i<n;i++){ for(int j=0;j<n;j++)printf("%d ",a[i][j]);printf("\n"); } } mat operator^(int k)const{ mat res;res.initE(); mat m=*this; //res.out();m.out(); while(k>0){ if(k&1)res=res*m; m=m*m;k>>=1; } return res; } }; int mp[1010]; int ans=0; int ed; void dfs(int now){ if(now==ed){ int c1,c2; c1=c2=0; for(int i=0;i<ed;i++){ if(mp[i]==0)c1++; if(mp[i]==1)c2++; } if(c1%2==0&&c2%2==0)ans++; return ; } for(int i=0;i<4;i++){ mp[now]=i; dfs(now+1); } } void init(int a[sz][sz]){ a[0][0]=3;a[0][1]=1; a[1][1]=4;a[1][2]=1; a[2][2]=2; } int main(){ mat m; m.a[0][0]=m.a[2][0]=2; mat q;init(q.a); int t; scanf("%d",&t); // m.out();q.out(); while(t--){ int k; scanf("%d",&k); printf("%d\n",((q^(k-1))*m).a[0][0]); } return 0; }