P1539题解
P1539题解
1.分析
数据范围:
则
我们算一下时间复杂度,由于相邻不能同时为 1,所以很多情况都被舍掉,所以当
但题目给出的矩阵有些数已经填好,无法改变,这怎么处理呢?
设
最后的 dp 就比较简单了,设
状态转移方程:
最终答案:
初始化:
时间复杂度:
2.Code
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int mod=10007;
int n,m=15,ans,t[230],s[230],c[1600],f[230][1600];
char a[230][230],b[230][230];
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%s",a[i]+1);
//如果n<m,将矩阵顺时针旋转90度,以保证列数m<=15
if(n<m) {
swap(n,m);
memcpy(b,a,sizeof(b));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)a[i][j]=b[m-j+1][i];
}
//预处理s,t数组
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(a[i][j]=='1')s[i]+=1<<m-j;
if(a[i][j]=='0')t[i]+=1<<m-j;
}
}
//预处理每行方案,存入数组c
for(int i=0;i<1<<m;i++)
if(!(i>>1&i))c[++c[0]]=i;
f[0][1]=1;
for(int i=1;i<=n;i++) {
for(int j=1;j<=c[0];j++) {
//判断方案是否合法
if((s[i]&c[j])!=s[i])continue;
if((t[i]&(~c[j]))!=t[i])continue;
for(int k=1;k<=c[0];k++)
if(!(c[j]&c[k]))f[i][j]=(f[i][j]+f[i-1][k])%mod;
}
}
for(int i=1;i<=c[0];i++)ans=(ans+f[n][i])%mod;
printf("%d",ans);
return 0;
}