USACO 2006 November Gold Corn Fields /// 状压 oj23941

题目大意:

输入n m

接下来n行m列

0表示不能种玉米 1表示能

要求种玉米位置的上下左右四连通区域不能种玉米

输出方案数

Sample Input

2 3
1 1 1
0 1 0

Sample Output

9

Hint

Number the squares as follows:

1 2 3
  4

There are four ways to plant only on one squares (1, 2, 3, or 4), three ways to plant on two squares (13, 14, or 34), 1 way to plant on three squares (134), and one way to plant on no squares. 4+3+1+1=9.

 
#include <bits/stdc++.h>
#define MOD 100000000
using namespace std;
int mir[13],may[1<<12],dp[13][1<<12];
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        int num=0;
        for(int i=0;i<(1<<m);i++)
            if((i&(i<<1))==0) may[num++]=i;
        /// 等于0说明符合条件 may[]保存所有可能放置
        /// 左移一位后,若不为0,说明有相邻两位同时为1
        /// 如 i 为011,则 i<<1 为110,(011&110) = 1
        
        memset(mir,0,sizeof(mir));
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            {
                int tmp; scanf("%d",&tmp);
                if(tmp==0) mir[i]|=1<<j; 
                /// mir[]可理解为 i 行的镜像拓本
            }
            
        memset(dp,0,sizeof(dp));
        for(int i=0;i<num;i++)/// 枚举所有可能 判断与拓本是否可匹配
            if((mir[0]&may[i])==0) dp[0][may[i]]=1;
        /// 等于0说明may[i]为该行的可能放置
            
        for(int i=0;i<n-1;i++) // 枚举各行 从本行推下一行 所以只需到n-1行
            for(int j=0;j<num;j++) // 枚举所有可能放置
                if((mir[i]&may[j])==0)/// 当与本行可匹配时
                { // 该放置是本行可能出现的符合条件的放置时
                    for(int k=0;k<num;k++)// 枚举所有可能(下一行的)
                        if(((mir[i+1]&may[k])==0)&&((may[k]&may[j])==0))
                        /// 该放置为下一行的可能放置(与下一行的拓本可匹配)
                        /// 且 与本行的放置可匹配时
                            dp[i+1][may[k]]+=dp[i][may[j]];
                }
        int ans=0;
        for(int i=0;i<num;i++)// 枚举所有可能放置(最后一行)
            ans=ans+dp[n-1][may[i]],ans%=MOD; 
        // 由前往后推 所以只要最后一行存在这种放置的方案 
        // 则表示这种方案也符合前面所有行的放置
        printf("%d
",ans);
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zquzjx/p/9077930.html