P1879 玉公尺田Corn Fields題解

2021-09-19 04:46:43 字數 1940 閱讀 9783

農場主john新買了一塊長方形的新牧場,這塊牧場被劃分成m行n列(1 ≤ m ≤ 12; 1 ≤ n ≤ 12),每一格都是一塊正方形的土地。john打算在牧場上的某幾格里種上美味的草,供他的奶牛們享用。

遺憾的是,有些土地相當貧瘠,不能用來種草。並且,奶牛們喜歡獨佔一塊草地的感覺,於是john不會選擇兩塊相鄰的土地,也就是說,沒有哪兩塊草地有公共邊。

john想知道,如果不考慮草地的總塊數,那麼,一共有多少種種植方案可供他選擇?(當然,把新牧場完全荒廢也是一種方案)

2 31 1 1

0 1 0

看到兩個數m n都小於12,第一反應就是狀壓,用二進位制來表示每一行的狀態,例如,j=13時,j 用二進位制表示為1101,表示1號位置種草,2號位置種草,3號位置不種草,4號位置種草。

首先輸入m n ,然後輸入地圖,這裡有一種快捷方式記錄地圖,相當於把每一行的狀態壓縮為乙個數字儲存,列如樣例第一行1 1 1壓縮為7,這樣會使後面的操作簡單些

for

(int i=

1;i<=m;i++

)for

(int j=

0;j)

本題有兩個約束條件,第一是不能 0 位置種草,第二時不能有連續的草叢

先解決第乙個條件,由於之前已經記錄了壓縮後的地圖狀態了,假設此時第i行地圖狀態為mp[i],第i行的狀態為k, 假設mp[i]二進位制的第j位為0,那麼k的第j位就只能是0,如果mp[i]j位為1,那麼k的第j位可以是01,這裡我們用一種運算——|,或運算

用 (mp[i] | k) == mp[i] 來判斷合法

畫圖理解下

第二個條件比較簡單,設當前行狀態為 j ,上一行狀態為 k

j & ( j >>1 )可以快速判斷是否有連續的 1

j & k 可以快速判斷是否與上一行狀態有衝突

兩個條件都滿足時候 轉移狀態dp[i] [j] += dp[i-1] [l]

附上**

#include

.h>

using namespace std;

int n,m,sum=

0,mod=

1e9;

int mp[

105]

=,dp[13]

[1<<12]

;//mp儲存地圖情況,dp列舉每一種狀況

int main()

for(int l=

0;l<

;l++

)//初始化第一行的情況

for(int i=

2;i<=m;i++)}

}for

(int i=

0;i<

;i++

) cout<

return0;

}

洛谷 1879 玉公尺田

題目描述 農場主john新買了一塊長方形的新牧場,這塊牧場被劃分成m行n列 1 m 12 1 n 12 每一格都是一塊正方形的土地。john打算在牧場上的某幾格里種上美味的草,供他的奶牛們享用。遺憾的是,有些土地相當貧瘠,不能用來種草。並且,奶牛們喜歡獨佔一塊草地的感覺,於是john不會選擇兩塊相鄰...

Luogu P1879玉公尺田(狀壓DP)

題目鏈結 資料範圍這麼小,難度又這麼大,一般就是狀態壓縮dp了。對輸入進行處理,二進位制表示每一行的草地狀況。如111表示這一行草地肥沃,壓縮成7.所以f i j 表示第i行狀態為j時的方案數 狀態j指的是乙個二進位制集合,有牛在吃草的位置是1,不再吃草的位置是0 f i j sum f i 1 k...

P1825 玉公尺田迷宮

有了上次題目看錯的教訓後再不敢隨便看題了usaco太坑,這題絕對不水,傳送門還特別玄學自然 短不了 const z array 1.4,1.2 of 1.1 1,0 0,1 1,0 0,1 var i,j,k longint m,n longint pdx,pdy longint csmx,csmy...