洛谷P1879题解
P1879
Solution
分析
首先把矩阵存在 \(a[i][j]\) 里
然后用一个数组b存每一行i,里的状态,用加法来进计算
用一个 \(meiju\) 数组 枚举出 1-2^n (左开右闭区间)所有满足题意的方案
初始化 \(f[0][0]\) 啥都不种也是一种方案
双重循环,分别枚举行数和 1-2^n(左开右闭区间)的所有方案数
如果此时j合法即 \(meiju[j]\) 存在,并且 \(j\) 必须是 \(b[i]\) 的一个子集
然后继续枚举k 1-2^n(左开右闭区间)当k和j没有交集时进行状态转移 \(f[i][j]\) = ( \(f[i][j]\) + \(f[i-1][k]\) ) % \(Mod\)
此时是正序枚举,若倒叙可将 \(f[i-1][k]\) 改为 \(f[i+1][k]\)
code
/*
work by Simon
*/
#include<bits/stdc++.h>
#define maxn 4096
using namespace std;
const int Mod=1e9;
int n,m,ans;
int a[13][13],b[maxn],meij[maxn],f[13][maxn];
bool pd(int k)
{
if((!(k&(k<<1)))&&(!(k&(k>>1))))
return true;
return false;
}
int main()
{
std::ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>m;
int MAX=(1<<m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
b[i]=(b[i]<<1)+a[i][j];
}
f[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<MAX;j++)
{
if(pd(j)&&((b[i]&j)==j))
for(int k=0;k<MAX;k++)
if((k&j)==0)
f[i][j]=(f[i][j]+f[i-1][k])%Mod;
}
for(int i=0;i<MAX;i++)
ans=(ans+f[n][i])%Mod;
cout<<ans;
return 0;
}

浙公网安备 33010602011771号