核💗: 对状态转移矩阵的理解---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来说,实在是太难了。快帮他算算什么时候应该拍手吧。
抓住青春的尾巴。。。