poj3254 Corn Fields

【题意】

输入一个m*n的矩阵可以放牛,其中有一些地方不能放牛,放牛的规则是牛与牛
之间只要不相邻就可以,可以不放,问有多少种方案。1 ≤ M ≤ 12; 1 ≤N ≤ 12
。输出结果要对1e8取余。
 
【分析】
基础的状压dp问题,f[i][j]表示第i行状态为j的方案数
我们可以枚举每一行的可行状态和上一行的状态,如果没有挨着的情况,那么就可以直接进行更新答案
 
【代码】
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod=1e8;
int n,m;
int able[5005],tot;
bool check(int x)
{
    if(x&(x<<1)) return false;
    return true;
}
void init()
{
    for(int i=0;i<(1<<m);i++)
        if(check(i)) able[++tot]=i;
}
int field[13],f[13][5005];
int main()
{

    scanf("%d%d",&n,&m);
    int x;
    init();
    for(int i=1;i<=n;i++)
    {
        int state=0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&x);
            x=(!x);
            state=(state<<1)+x;
        }
        field[i]=state;
    }
    for(int i=1;i<=tot;i++)
    {
        if(able[i]&field[1]) continue;
        f[1][i]=1;
    }
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=tot;j++)
        {
            int st=able[j];
            if(st&field[i]) continue;
            for(int k=1;k<=tot;k++)
            {
                if(st&able[k]) continue;
                f[i][j]=(f[i][j]+f[i-1][k])%mod;
            }
        }
    }
    int ans=0;
    for(int i=1;i<=tot;i++) ans=(ans+f[n][i])%mod;
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2021-09-08 22:50  andyc_03  阅读(22)  评论(0编辑  收藏  举报