POJ 3254 Corn Fields 狀態壓縮DP

來源:互聯網
上載者:User

題意:John買了一塊矩形的地。他想在上面種草餵奶牛,但是有的格子比較貧瘠不能種草,我們用0表示。否則用1表示。由於奶牛不喜歡擠在一起,所以任何兩個相鄰格子不能都種上草。現在問你有多少種種草的方式。當然,不種草也算一種方式。
題解:第 i 行的第 j 中狀態由前一行決定。故枚舉第 i - 1 行中所有與 j 相容的狀態。

#include <iostream>using namespace std;#define Num 100000000#define N (1<<13)bool state[13][N]; /* state[i][j] 表示第i行可以化成狀態j,每一行的其他狀態都是由其初始狀態轉移的到得 */int dp[13][N], row[13]; /* row[i]表示第i行的初始狀態 */int Max, R, C;void calState ( int i ){for ( int k = 0; k <= Max; k++ ){   if ( ((~row[i]) & k) || (k & (k<<1)) )  /* 一開始用的是(row[i]&(~k)),沒注意到位元運算會修改掉原來的值,WR了很久 */ state[i][k] = 0;else state[i][k] = 1;}}void operDp (){int i, j, k;for ( i = 0; i <= Max; i++ ) /* 預先把第一行的值求出來 */{if ( state[1][i] )dp[1][i] = 1;}for ( i = 2; i <= R; i++ ){for ( j = 0; j <= Max; j++ ){if ( ! state[i][j] ) /* 若第i行的狀態j不存在,直接用第i行下一個狀態 */continue;    for ( k = 0; k <= Max; k++ )    if ( state[i-1][k] && !(j & k) ) /* 若第i-1行的狀態k存在,且狀態k與狀態j直接不衝突,則dp[i][j]累加 */dp[i][j] += dp[i-1][k];dp[i][j] %= Num;}}}int main(){scanf("%d%d",&R,&C);Max = 1 << C;memset(state,0,sizeof(state));memset(dp,0,sizeof(dp));int i, j, flag;for ( i = 1; i <= R; i++ ){for ( j = 0; j < C; j++ ){    scanf("%d",&flag);    row[i] |= ( flag << j );}calState ( i );}operDp();int ans = 0;for ( i = 0; i <= Max; i++ )ans += dp[R][i];printf("%d\n",ans % Num);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.