题意
有 n 个位置排成一行,可以放 m 种妹子。每个位置可以放也可以不放,规定某些妹子不能相邻,求方案数。
分析
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll qmul(ll x,ll y,ll p){ //快速乘 x%=p; y%=p; ll ans=0; while(y){ if(y&1){ ans+=x; if(ans>=p) ans-=p; //这样写不能有负数 } x<<=1; if(x>=p) x-=p; y>>=1; } return ans; } struct Mat{ int r,c; ll m[110][110]; Mat(){ memset(m,0,sizeof(m)); } }; Mat mmul(Mat x,Mat y,ll p){ Mat ans; ans.r=x.r; ans.c=y.c; for(int i=0;i<x.r;i++) for(int k=0;k<x.c;k++) for(int j=0;j<y.c;j++){ ans.m[i][j]+=qmul(x.m[i][k],y.m[k][j],p); if(ans.m[i][j]>=p) ans.m[i][j]-=p; } return ans; } Mat mpow(Mat x,ll y,ll p){ Mat ans; ans.r=x.r; ans.c=x.c; for(int i=0;i<ans.c;i++) ans.m[i][i]=1; while(y){ if(y&1) ans=mmul(ans,x,p); x=mmul(x,x,p); y>>=1; } return ans; } const ll mod = 1000000007; Mat T, A; int n, m; char s[110]; int main(){ scanf("%d%d", &n, &m); T.r = T.c = m+1; for(int i = 0;i < m;i++) { scanf("%s", s); for(int j = 0;j < m;j++) T.m[i][j] = 1- (s[j] - '0'); T.m[i][m] = 1; } for(int i = 0;i <= m;i++) T.m[m][i] = 1; //补充一类”空妹子“ T = mpow(T, n-1, mod); A.r = 1, A.c = m+1; for(int i = 0;i <= m;i++) A.m[0][i] = 1; A = mmul(A, T, mod); ll ans = 0; for(int i = 0;i <= m;i++) ans = (ans + A.m[0][i]) % mod; printf("%lld ", ans); return 0; }
没处交题,只能找别人题解的代码对拍,应该没错吧??
参考链接:https://blog.csdn.net/FSAHFGSADHSAKNDAS/article/details/52745912