poj3254 Corn Fields (狀態壓縮dp)

來源:互聯網
上載者:User
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;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.