洛谷P1879玉米田
思路:
第一次自己把状压dp写出来,有点激动。
dp[i][j]表示在第i层的状态j。
在预处理的时候判断下每层的合法情况。设第一层可选的状态都是1。
代码:
#include<bits/stdc++.h>
#define pii pair<int,int>
#define ll long long
const int N=1e6+10;
const int mod=1e9;
const int maxn=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
const int inf=99999999;
using namespace std;
int n,m,a[15][15],dp[15][1<<15]={0},sta[15][1<<15],len[15]={0};
int judge(int p,int x)
{
int i;
for(i=1;i<=m;i++)
if((x>>(m-i))&1==1 && a[p][i]==0)
return 0;
return 1;
}
void pre()
{
int i,j;
for(i=1;i<=n;i++)
for(j=0;j<(1<<m);j++)
if((((j>>1)|(j<<1))&j)==0 && judge(i,j))
sta[i][++len[i]]=j;
for(i=0;i<(1<<m);i++)
for(j=1;j<=len[1];j++)
if(sta[1][j]==i)
dp[1][i]=1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int i,j,k;
cin>>n>>m;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
cin>>a[i][j];
pre();
for(i=2;i<=n;i++)
for(j=1;j<=len[i-1];j++)
{
int x=sta[i-1][j];
for(k=1;k<=len[i];k++)
{
int y=sta[i][k];
if((y&x)==0)
dp[i][y]+=dp[i-1][x];
}
}
int ans=0;
for(i=0;i<(1<<m);i++)
ans=(ans+dp[n][i])%mod;
cout<<ans<<endl;
return 0;
}