jzoj 1266. 玉米田(cowfood.pas/c/cpp)

Description
  農民 John 購買了一處肥沃的矩形牧場,分成M*N(1 <= M <= 12; 1 <= N <= 12)個格子。他想在那裏的一些格子中種植美味的玉米。遺憾的是,有些格子區域的土地是貧瘠的,不能耕種。精明的 FJ 知道奶牛們進食時不喜歡和別的牛相鄰,所以一旦在一個格子中種植玉米,那麼他就不會在相鄰的格子中種植,即沒有兩個被選中的格子擁有公共邊。他還沒有最終確定哪些格子要選擇種植玉米。    作爲一個思想開明的人,農民 John 希望考慮所有可行的選擇格子種植方案。由於太開明,他還考慮一個格子都不選擇的種植方案!請幫助農民 John 確定種植方案總數。

Input
  Line 1: 兩個用空格分隔的整數 M 和 N
  Lines 2…M+1: 第 i+1 行描述牧場第i行每個格子的情況, N 個用空格分隔的整數,表示 這個格子是否可以種植(1 表示肥沃的、適合種植,0 表示貧瘠的、不可種植)

Output
  Line 1: 一個整數: FJ 可選擇的方案總數 除以 100,000,000 的餘數。

Sample Input
2 3
1 1 1
0 1 0

Sample Output
9

Data Constraint

Hint
【樣例說明】
給可以種植玉米的格子編號:+
1 2 3
4
只種一個格子的方案有四種 (1, 2, 3, 或 4),種植兩個格子的方案有三種 (13, 14, 或 34),種植三個格子的方案有一種 (134),還有一種什麼格子都不種。 4+3+1+1=9。

//written by zzy

題目大意:

在一個圖中,只能在 11 的格子種,且種了的格子上下左右不能種,求種的方案數。

題解:

觀看數據規模,不難發現是狀壓dp,狀態 xx 二進制下的 第 ii11 表,第 ii 種了
f[i,j]f[i,j] 爲第 ii 行,狀態爲 jj 的方案數,考慮如何轉移,
先將地圖,每一行不合法的狀態處理處來
因爲只有上一行能影響這一行的轉移,所以易得
f[i,j]=f[i1,k](kf[i,j]=∑f[i-1,k],(k & j)!=0jj)!=0,j 合法//上一行的格子沒種,這一行的格子能種。

#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 14
#define Mod 100000000
using namespace std;

int i,j,k,n,m,ans,x;
int map[N],f[N][1<<N];
bool g[N];

int main()
{
	freopen("cowfood.in","r",stdin);
	freopen("cowfood.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (i=1;i<=n;i++) 
	 for (j=1;j<=m;j++) {
	  scanf("%d",&x);
	  if (x) map[i]|=1<<(m-j);
    }
    for (i=0;i<=(1<<m)-1;i++) g[i]=1;
	for (i=0;i<=(1<<m)-1;i++)
	 for (j=2;j<=m;j++)
	  if (((i&(1<<(j-1)))!=0)&&((i&(1<<(j-2)))!=0)) 
	   g[i]=0;
	for (j=0;j<=(1<<m)-1;j++) 
	 if (g[j]&&(map[1]|j)==map[1]) f[1][j]=1;
	for (i=2;i<=n;i++)
	 for (j=0;j<=(1<<m)-1;j++) 
	  if (g[j]&&((map[i]|j)==map[i]))
	   for (k=0;k<=(1<<m)-1;k++)
	    if ((k&j)==0)
	     f[i][j]=(f[i][j]+f[i-1][k])%Mod;
	for (j=0;j<=(1<<m)-1;j++)
	 ans=(ans+f[n][j])%Mod;
	printf("%d",ans);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章