题目链接(VJ):https://nanti.jisuanke.com/t/A2022
计蒜客:https://nanti.jisuanke.com/t/A2022
题意:有N个小时,有三种食物(用1 ,2 ,3代替好了),每个小时要吃一种食物,要求任意连续三个小时不能出现111,222,333,132,231,313,323
的方案数
题解:最重要的是能找到这个转移关系,转移就是在增加一种食物,可以根据要求推出下面的递推矩阵.
然后直接矩阵快速幂就好了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MOD = 1e9+7; 4 const int maxn = 20; 5 #define mod(x) ((x)%MOD) 6 typedef long long ll; 7 struct martix{ 8 ll a[maxn][maxn]; 9 friend martix operator * (martix x,martix y) 10 { 11 martix ans; 12 for(int i = 1;i <= 9;i++) 13 { 14 for(int j = 1;j <= 9;j++) 15 { 16 ll res = 0; 17 for(int k = 1;k <= 9;k++) 18 res += mod((ll)x.a[i][k]*y.a[k][j]); 19 ans.a[i][j] = mod(res); 20 } 21 } 22 return ans; 23 } 24 friend martix operator ^ (martix x,ll n) 25 { 26 martix unit; 27 memset(unit.a,0,sizeof(unit.a)); 28 for(int i = 1;i <= 9;i++) unit.a[i][i] = 1; 29 while(n) 30 { 31 if(n&1) unit = unit * x; 32 x = x * x; 33 n >>= 1; 34 } 35 return unit; 36 } 37 }; 38 int main() 39 { 40 ll t,n; 41 cin>>t; 42 while(t--) 43 { 44 cin>>n; 45 if(n == 1) cout<<3<<endl; 46 else if(n == 2) cout<<9<<endl; 47 else 48 { 49 martix ans; 50 ll num[10][10] = { 51 0,0,0,0,0,0,0,0,0,0, 52 0,0,1,1,0,0,0,0,0,0, 53 0,0,0,0,0,1,1,0,0,0, 54 0,0,0,0,0,0,0,0,1,1, 55 0,1,1,0,0,0,0,0,0,0, 56 0,0,0,0,1,0,1,0,0,0, 57 0,0,0,0,0,0,0,1,1,1, 58 0,1,0,1,0,0,0,0,0,0, 59 0,0,0,0,1,1,1,0,0,0, 60 0,0,0,0,0,0,0,1,1,0, 61 }; 62 for(int i = 1;i <= 9;i++) 63 { 64 for(int j = 1;j <= 9;j++) 65 { 66 ans.a[i][j] = num[i][j]; 67 } 68 } 69 ans = ans ^ (n-2); 70 ll res = 0; 71 for(int i = 1;i <= 9;i++) 72 { 73 for(int j = 1;j <= 9;j++) 74 { 75 res += mod(ans.a[i][j]); 76 } 77 } 78 cout<<mod(res)<<endl; 79 } 80 } 81 return 0; 82 }