poj3524之状态压缩

来源:互联网 发布:学数据挖掘的去金融 编辑:程序博客网 时间:2024/05/16 19:44
Corn Fields
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 16969 Accepted: 8967

Description

Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yummy corn for the cows on a number of squares. Regrettably, some of the squares are infertile and can't be planted. Canny FJ knows that the cows dislike eating close to each other, so when choosing which squares to plant, he avoids choosing squares that are adjacent; no two chosen squares share an edge. He has not yet made the final choice as to which squares to plant.

Being a very open-minded man, Farmer John wants to consider all possible options for how to choose the squares for planting. He is so open-minded that he considers choosing no squares as a valid option! Please help Farmer John determine the number of ways he can choose the squares to plant.

Input

Line 1: Two space-separated integers: M and N 
Lines 2..M+1: Line i+1 describes row i of the pasture with N space-separated integers indicating whether a square is fertile (1 for fertile, 0 for infertile)

Output

Line 1: One integer: the number of ways that FJ can choose the squares modulo 100,000,000.

Sample Input

2 31 1 10 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.

Source

USACO 2006 November Gold


题目大意:现在给出一个n*m的土地,为1代表为草地,0代表沼泽,现在可以把牛放在草地上,要求任意两头牛之间不能相邻,求一共由多少种放法。


题目分析:截取的大神的分析。

1.首先考虑一下,每一行该怎么分配牛才不会让他们相邻,可以用状态压缩,0表示不放牛,1表示放牛,枚举一下有多少种可行的方案并纪录下来

2.接着考虑一下,因为不能相邻,而相邻的行之间又会相互影响。 
考虑到第一行是比较特殊的,可以先枚举第一行的解决方案,接下来再枚举其他行。 
在枚举其他行的情况时,要考虑和上一行的方案是否能共存,再考虑一下该方案是否可行(有沼泽影响) 
如何判断该方案是否可行,可以先预处理一下地图,将地图也压缩成一个二进制数,0表示草地,1表示沼泽,然后将要枚举的方案和该行状态进行与运算,如果相与结果不为0,表示有牛放在了沼泽地,那么方案就不可行了 
判断和上一行能否共存的判断和上面判断差不多,用该行的方案和上一行方案进行与运算,如果结果不为0,表示有两头牛放在了同一列,那么方案不可行

代码:

/*******************************************************https://www.cnblogs.com/lytwajue/p/7142391.htmlhttp://blog.csdn.net/accry/article/details/6607703*******************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>using namespace std;const int maxm=20;const int maxn=10000;const int mod=100000000;int r,c,cnt;int row[maxm],state[maxn],dp[maxm][maxn];void init(){    int t;    memset(dp,0,sizeof(dp));    memset(row,0,sizeof(row));    for(int i=0;i<r;i++){        for(int j=0;j<c;j++){            cin>>t;            if(!t){                row[i]=row[i]|(1<<j);            }        }    }    cnt=0;    for(int i=0;i<(1<<c);i++){        if(i&(i<<1)){            continue;        }        state[cnt++]=i;    }    for(int i=0;i<cnt;i++){        if(state[i]&row[0]) continue;        dp[0][i]=1;    }    for(int i=1;i<r;i++){        for(int j=0;j<cnt;j++){            if(state[j]&row[i]) continue;            for(int k=0;k<cnt;k++){                if(row[i-1]&state[k])   continue;                if(state[j]&state[k])   continue;                dp[i][j]=(dp[i-1][k]+dp[i][j])%mod;            }        }    }}int solve(){    int ans=0;    for(int i=0;i<cnt;i++){        ans=(ans+dp[r-1][i])%mod;    }    return ans;}int main(){    while(cin>>r>>c)    {        init();        cout<<solve()<<endl;    }    return 0;}


原创粉丝点击