POJ 3254 Corn Fields

Corn Fields

题目来源: http://poj.org/problem?id=3254

题目大意:一个人买了一个N*M个方格组成的农场,有部分方格不能种植。现在需要种草给牛吃,而牛又不喜欢挨着吃(don’t share an edge–>两个方格无公共边),不种草也算一种方案,求种植方案数。


此题与Mondriaan's Dream 类似,就不多讲了。

#include <iostream>
#include <memory.h>
#define MOD  100000000
using namespace std;
const int maxn=15;
int isFertile[maxn][maxn];
int f[maxn][1<<maxn];
int n,m;
void dfs(int s,int p,int *a,int &tail,int row)
{
    if(p==m)
    {
        int k;
        for(k=0;k<m;k++)
        {
            if(s&(1<<k)&&(isFertile[row][k]==0||(s&(1<<(k+1)))))     break;
        }
        if(k>=m)
        {
            a[tail++]=s;
        }
        return ;
    }
    if((s&(1<<p))==0) {dfs(s,p+1,a,tail,row);}
    else
    {
        dfs(s,p+1,a,tail,row);
        dfs(s^(1<<p),p+1,a,tail,row);
    }
}
int dp(int row,int s)
{
    if(f[row][s]!=-1)   return f[row][s]%MOD;
    int q[1<<maxn],head=0,tail=0;
    int s1=~s;
    s1=s1&((1<<m)-1);
    for(int k=0;k<m;k++)
    {
        if(!isFertile[row][k])  s1=s1^(1<<k);
    }
    dfs(s1,0,q,tail,row);

    f[row][s]=0;
    if(row==n-1)    return f[row][s]=tail%MOD;
    for(head=0;head<tail;head++)
    {
        f[row][s]=(f[row][s]+dp(row+1,q[head]))%MOD;
    }
    return f[row][s];
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
    for(int j=0;j<m;j++)
    cin>>isFertile[i][j];
    memset(f,-1,sizeof(f));
    int q[1<<maxn],head=0,tail=0;
    for(int s=0;s<(1<<m);s++)
    {//枚举第一行的所有合法状态
        int k;
        for(k=0;k<m;k++)
        {
            if(s&(1<<k)&&(isFertile[0][k]==0||(s&(1<<(k+1)))))     break;
        }
        if(k>=m)    {q[tail++]=s;}
    }
    if(n==1)    {cout<<tail<<endl;return 0;}
    int sum=0;
    for(head=0;head<tail;head++)
    sum=(sum+dp(1,q[head]))%MOD;
    cout<<sum<<endl;
    return 0;
}

你可能感兴趣的:(C++,c,C#,F#,J#)