Corn Fields
Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
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.題意:給出一個10矩陣 從中取有限個1 求沒有上下左右沒有相鄰1的排列總數解題思路:1 先把每一排可以滿足要求的排列情況枚舉出來2從題目給的每一行裡面挑一種可以的情況 再從上一行挑一種可以的情況 要兩行加起來也可以 3dp[i][state]=dp[i][state'] state'是所有滿足state上一行的排列 總數全部加起來 最後得到答案4注意位元運算
#include<iostream>#include<cstring>#include<cstdio>using namespace std;int p,q,sum,pq[20],can[1<<12],dp[20][1<<12];int main(){ int i,j,k,l,a; while(~scanf("%d%d",&p,&q)) { memset(pq,0,sizeof(pq)); memset(can,0,sizeof(can)); memset(dp,0,sizeof(dp)); for(i=0;i<p;i++)//把每一行讀的數取反存在pq裡 那麼pq[i]=1的時候下一行的i位置才能取1 pq[i]=0時下一行只能取0 for(j=0;j<q;j++) { scanf("%d",&a); if(!a) pq[i]+=(1<<(q-j-1)); } for(i=0,j=0;i<(1<<q);i++)//用can存 在一行全部為1中挑選出 所有沒有相鄰1的排列情況 if((i&(i<<1))==0) can[j++]=i;//j最後的值就是一共有多少種排列數 for(i=0;i<j;i++) if((pq[0]&can[i])==0) dp[0][i]=1; //初始化dp[0] can[]其實是作為對照 後面符合的情況都是從這裡挑出來再比較可不可以 for(i=1;i<p;i++) for(k=0;k<j;k++) if((pq[i]&can[k])==0)//以can做對照 挑一個可以的pq排列 for(l=0;l<j;l++)//再挑一個可以的can排列 if((pq[i-1]&can[l])==0&& (can[k]&can[l])==0)//這一排跟上一排不衝突就符合 dp[i][k]=(dp[i][k]+dp[i-1][l])%100000000;//題目要求輸出mod100000000的值 for(i=0,sum=0;i<j;i++) sum+=dp[p-1][i]; printf("%d\n",sum%100000000); } return 0;}