Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 8691 | Accepted: 4634 |
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
Output
Sample Input
2 3 1 1 1 0 1 0
Sample Output
9
Hint
1 2 3 4
这种题将状态用数字表示,m位二进制数范围是[00...00,11...11],0和1的个数均为m
此题有一些限制条件:
每行有肥沃区(用1表示)和非肥沃区(用0表示),那么每行都可以用一个数字表示。
有牛用1表示,没牛用0表示,则一行如何放置牛也可用一个数字,因为牛必须在肥沃区,也就是原先该行有1的地方必须覆盖该行放置牛的状态(有1的地方),这个用按位或运算就可以了,如果覆盖就等于原先的状态。
本行不能有相邻的牛,也就是不能有相邻的1,我们将数字左移一位,最左一位和最右一位都与0&,而中间部分刚好是相邻位&,若没有相邻1,那显然结果为0.
与上行在同一列不能有牛,和上面类似,直接拿上一行放置牛的状态与本行&,结果为0,就是符合条件的。
dp就按照常规来,dp[i][s]表示第i行为状态s的种数,显然dp[i][s]=sigma(dp[i-1][t]),((t&s)==0&&t,s均为合法状态)
代码:
#include<cstdio> #include<iostream> #include<cstring> #define Maxn 4100 using namespace std; const int mod=100000000; int r[15],dp[15][Maxn]; int st[Maxn]; int main() { int n,m,x; while(cin>>n>>m){ for(int i=1;i<=n;i++){ r[i]=0; for(int j=1;j<=m;j++){ cin>>x; r[i]=r[i]<<1|x; } } int top=0; for(int i=0;i<1<<m;i++) //预处理本行相邻位不同为1 if(!(i&i<<1)) st[top++]=i; memset(dp,0,sizeof dp); dp[0][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<top;j++){ if((st[j]|r[i])!=r[i]) continue; //与本行冲突 for(int k=0;k<top;k++) //i-1行非法状态dp均为0,因此直接加在dp[i][]上 if(!(st[j]&st[k])) //与上一行同位不同为1 dp[i][st[j]]=(dp[i][st[j]]+dp[i-1][st[k]])%mod; } int ans=0; for(int i=0;i<top;i++) ans=(ans+dp[n][st[i]])%mod; printf("%d\n",ans); } return 0; }