核💗: 對狀態轉移矩陣的理解---A(x,y) 從x狀態轉移y狀態有多少種可能; B=A^n----B(x,y)表示經過n輪轉移之后從x到y有多少轉換方式
NO.1---方格填數
鏈接:https://ac.nowcoder.com/acm/contest/190/J
來源:牛客網
題目描述
給一個m x n的方格,Applese想要給方格填上顏色,每個格子可以是黑色或者白色。他要求左右相鄰兩格不能同為白色且相鄰兩列不能全為黑色。
求滿足條件的方案數。
求滿足條件的方案數。
輸入描述:
輸入兩個整數m, n。(1 ≤ m ≤ 5, 1 ≤ n ≤ 1018
)。
輸出描述:
輸出答案對109
+ 7取模的結果。
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const LL mod=1e9+7; 5 int tot; 6 struct mat { 7 LL m[50][50]; 8 mat operator*(const mat& t) const { 9 mat ans; 10 for (int i=0;i<tot;i++) 11 for (int j=0;j<tot;j++) { 12 LL x=0; 13 for (int k=0;k<tot;k++) 14 x=( m[i][k]*t.m[k][j]%mod+x )%mod; 15 ans.m[i][j]=x; 16 } 17 return ans; 18 } 19 }; 20 mat A; 21 int m;LL n; 22 mat q_pow (mat X,LL k) { 23 mat B; 24 for (int i=0;i<tot;i++) B.m[i][i]=1; 25 while (k) { 26 if (k&1) B=B*X; 27 X=X*X; 28 k=(k>>1); 29 } 30 return B; 31 } 32 int main () 33 { 34 scanf ("%d %lld",&m,&n); 35 tot=(1<<m); 36 for (int i=0;i<tot;i++) 37 for (int j=0;j<tot;j++) { 38 if (i==0&&j==0) continue; 39 if (!(i&j)) A.m[i][j]=1; 40 } 41 A=q_pow (A,n-1); 42 LL sum=0; 43 for (int i=0;i<tot;i++) 44 for (int j=0;j<tot;j++) 45 sum=(sum+A.m[i][j])%mod; 46 printf("%lld\n",sum); 47 return 0; 48 }
NO.2--方格填數
鏈接:https://ac.nowcoder.com/acm/contest/188/F
來源:牛客網
小w喜歡Van數列
小w有一個長度為n的由3和7構成的環狀序列
小w規定序列中任意相鄰的m個數,3的個數不能超過7的個數
小w想知道這樣的序列共有多少種 ,方案數對於998244353取mod
小w規定序列中任意相鄰的m個數,3的個數不能超過7的個數
小w想知道這樣的序列共有多少種 ,方案數對於998244353取mod
輸入描述:
一行兩個數n,m
輸出描述:
一個數表示對998244353取模后的方案數
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const LL mod=998244353; 5 LL n,m,dim; 6 bool check (int x) { 7 int tmp=x,sum=0; 8 while (tmp) { 9 if (tmp&1) sum++; 10 tmp=tmp>>1; 11 } 12 return sum>=(m+1)/2; 13 } 14 struct matrix { 15 LL a[40][40]; 16 friend matrix operator*(const matrix& x,const matrix& y) { 17 matrix ans; 18 for (int i=0;i<dim;i++) 19 if (check(i)) 20 for (int j=0;j<dim;j++) 21 if (check(j)) { 22 ans.a[i][j]=0; 23 for (int k=0;k<dim;k++) 24 ans.a[i][j]=(ans.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod; 25 } 26 return ans; 27 } 28 }; 29 matrix q_pow (matrix x,LL k) { 30 matrix ans; 31 for (int i=0;i<dim;i++) 32 for (int j=0;j<dim;j++) 33 if (i==j) ans.a[i][j]=1; 34 else ans.a[i][j]=0; 35 while (k) { 36 if (k&1) ans=ans*x; 37 x=x*x; 38 k=k>>1; 39 } 40 return ans; 41 } 42 matrix tra; 43 int main () 44 { 45 scanf ("%lld %lld",&n,&m); 46 dim=(1<<m); 47 for (int i=0;i<dim;i++)// 狀態描述: dp[i] :最后m位狀態是i的種類有多少種 48 for (int j=0;j<dim;j++) 49 if (check(i)&&check(j)&&(i&(1<<m-1)-1)==(j>>1)) { 50 tra.a[i][j]=1; 51 //cout<<i<<" "<<j<<" :"<<tra.a[i][j]<<endl; 52 } 53 matrix ans=q_pow (tra,n-m); 54 LL sum=0; 55 for (int i=0;i<dim;i++) if (check(i)) //最后枚舉初始狀態和最終狀態是否兼容 56 for (int j=0;j<dim;j++) if (check(j)) { 57 int flag=1; 58 for (int k=1;k<m;k++) 59 if ( check ( ( ((j<<k)|(i>>m-k)) )&(dim-1) ) ) flag++; 60 if (flag==m) sum=(sum+ans.a[i][j])%mod; 61 } 62 printf("%lld\n",sum); 63 return 0; 64 }
鏈接:https://ac.nowcoder.com/acm/contest/190/D
來源:牛客網
今天是個特殊的日子,CSL和他的小伙伴們圍坐在一張桌子上玩起了明七暗七的游戲。游戲規則是這樣的:
一個人報出一個起始數,接下來按照逆時針的順序輪流報數,如果碰到數是7的倍數或含有7,則拍手,下一個人接着報數。直到有一個人報錯了數字或者沒有及時拍手為止。
玩游戲嘛,當然得有懲罰。這么簡單的游戲對CSL的學霸小伙伴而言實在是太無腦了,輕輕松松數到上萬根本不在話下。但是對於數學是體育老師教的CSL來說,實在是太難了。快幫他算算什么時候應該拍手吧。