USACO 2006 November Gold Corn Fields /// 狀壓 oj23941
阿新 • • 發佈:2018-05-23
是否 square span 說明符 輸入 lds memset ace sin
題目大意:
輸入n m
接下來n行m列
0表示不能種玉米 1表示能
要求種玉米位置的上下左右四連通區域不能種玉米
輸出方案數
Sample Input2 3
1 1 1
0 1 0
9
HintNumber 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.
#include <bits/stdc++.h> #define MOD 100000000 using namespace std; int mir[13],may[1<<12],dp[13][1<<12]; int main() { int n,m; while(~scanf("%d%d",&n,&m)) { int num=0; for(int i=0;i<(1<<m);i++) if((i&(i<<1))==0) may[num++]=i;View Code/// 等於0說明符合條件 may[]保存所有可能放置 /// 左移一位後,若不為0,說明有相鄰兩位同時為1 /// 如 i 為011,則 i<<1 為110,(011&110) = 1 memset(mir,0,sizeof(mir)); for(int i=0;i<n;i++) for(int j=0;j<m;j++) { int tmp; scanf("%d",&tmp); if(tmp==0) mir[i]|=1<<j; /// mir[]可理解為 i 行的鏡像拓本 } memset(dp,0,sizeof(dp)); for(int i=0;i<num;i++)/// 枚舉所有可能 判斷與拓本是否可匹配 if((mir[0]&may[i])==0) dp[0][may[i]]=1; /// 等於0說明may[i]為該行的可能放置 for(int i=0;i<n-1;i++) // 枚舉各行 從本行推下一行 所以只需到n-1行 for(int j=0;j<num;j++) // 枚舉所有可能放置 if((mir[i]&may[j])==0)/// 當與本行可匹配時 { // 該放置是本行可能出現的符合條件的放置時 for(int k=0;k<num;k++)// 枚舉所有可能(下一行的) if(((mir[i+1]&may[k])==0)&&((may[k]&may[j])==0)) /// 該放置為下一行的可能放置(與下一行的拓本可匹配) /// 且 與本行的放置可匹配時 dp[i+1][may[k]]+=dp[i][may[j]]; } int ans=0; for(int i=0;i<num;i++)// 枚舉所有可能放置(最後一行) ans=ans+dp[n-1][may[i]],ans%=MOD; // 由前往後推 所以只要最後一行存在這種放置的方案 // 則表示這種方案也符合前面所有行的放置 printf("%d\n",ans); } return 0; }
USACO 2006 November Gold Corn Fields /// 狀壓 oj23941