1. 程式人生 > >牛客小白月賽7-J 方格填色

牛客小白月賽7-J 方格填色

思路:狀態壓縮+矩陣快速冪

對於狀態壓縮方程易得轉換方程

for(int i=2;i<=n;++i)
	for(int j=0;j<=s;++j)
		for(int k=0;k<=s;++k)
			if((j||k)&&!(j&k))	dp[i][j]=(dp[i][j]+dp[i-1][k])%MOD;

Code :

#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;

const int MOD=1e9+7;
const int MAX_S=35;
struct Matrix{
	LL a[MAX_S][MAX_S];
	Matrix(){memset(a,0,sizeof(a));}
	Matrix operator*(const Matrix &A){
		Matrix res=Matrix();
		for(int k=0;k<MAX_S;++k)
			for(int i=0;i<MAX_S;++i)
				for(int j=0;j<MAX_S;++j)
					res.a[i][j]=(res.a[i][j]+a[i][k]*A.a[k][j]%MOD)%MOD;
		return res;
	}
};
LL n,m;

int main()
{
	ios::sync_with_stdio(false);
	while(cin>>m>>n){
		int s=(1<<m)-1;
		Matrix t0=Matrix(),ans=Matrix();
		for(int i=0;i<MAX_S;++i)
			ans.a[i][i]=1;
		for(int i=0;i<=s;++i)
			for(int j=0;j<=s;++j)
				if((i||j)&&!(i&j))	t0.a[i][j]=1;
		--n;
		while(n){
			if(n&1)	ans=ans*t0;
			t0=t0*t0;
			n>>=1;
		}
		LL res=0;
		for(int i=0;i<=s;++i)
			for(int j=0;j<=s;++j)
				res=(res+ans.a[i][j])%MOD;
		cout<<res<<endl;
	}
	
	return 0;
}