bzoj 1725:Corn Fields牧场的安排

来源:互联网 发布:退火算法 matlab 编辑:程序博客网 时间:2024/06/05 05:47

Description

Farmer John新买了一块长方形的牧场,这块牧场被划分成M列N行(1<=M<=12; 1<=N<=12),每一格都是一块正方形的土地。FJ打算在牧场上的某几格土地里种上美味的草,供他的奶牛们享用。遗憾的是,有些土地相当的贫瘠,不能用来放牧。并且,奶牛们喜欢独占一块草地的感觉,于是FJ不会选择两块相邻的土地,也就是说,没有哪两块草地有公共边。当然,FJ还没有决定在哪些土地上种草。 作为一个好奇的农场主,FJ想知道,如果不考虑草地的总块数,那么,一共有多少种种植方案可供他选择。当然,把新的牧场荒废,不在任何土地上种草,也算一种方案。请你帮FJ算一下这个总方案数。

Input

* 第1行: 两个正整数M和N,用空格隔开

* 第2..M+1行: 每行包含N个用空格隔开的整数,描述了每块土地的状态。输入的第i+1行描述了第i行的土地。所有整数均为0或1,是1的话,表示这块土地足够肥沃,0则表示这块地上不适合种草

Output

* 第1行: 输出一个整数,即牧场分配总方案数除以100,000,000的余数


          感觉这是一道简单版的炮兵阵地?

      很容易想到这道题的状态为dp[i][state]表示考虑到第i行了,state中的0或1表示选或没选。

      接下来考虑转移,对于现在这一行的每个状态,肯定是由上一行的某个与它互相不干涉的状态转移而来,

      为了判断上下互相不干涉,我们只需要两个相与值为0即可判断,

      对于左右无相邻,我们可以讲当前state左移一位与当前state相与,如果为0,则说明没有相邻选中的了。

      对于不在贫瘠的草上,我们可以将贫瘠的草设为1,将当前状态与草地状态相与,如果为0,则说明没有选中的在贫瘠的草上了。

      最后考虑边界条件,对于开始,第0行全不选的答案为1,很套路的状态了。最终的答案便是,最后一行,所有状态的答案之和。

       下附AC代码。

#include<iostream>#include<stdio.h>#include<string.h>#define maxn 14using namespace std;typedef long long ll;const ll mod=100000000;ll n,m;ll dic[maxn];ll dp[maxn][(1<<maxn)];ll judge1(ll now){if((now&(now>>1))) return false;return true;}int main(){scanf("%lld%lld",&n,&m);for(ll i=0;i<n;i++)for(ll j=0;j<m;j++){ll x;scanf("%lld",&x);if(x==0)dic[i]|=(1<<j);}dp[0][0]=1;for(ll i=0;i<n;i++){for(ll state=0;state<(1<<m);state++){for(ll nex=0;nex<(1<<m);nex++){if(judge1(nex) && (state&nex)==0 && (nex&dic[i])==0){dp[i+1][nex]+=dp[i][state];if(dp[i+1][nex]>=mod)dp[i+1][nex]-=mod;} }}}ll ans=0;for(ll state=0;state<(1<<m);state++){ans+=dp[n][state];if(ans>mod)ans-=mod;}printf("%lld\n",ans);}


     

阅读全文
0 0
原创粉丝点击