1. 程式人生 > >[jzoj]2938.【NOIP2012模擬8.9】分割田地

[jzoj]2938.【NOIP2012模擬8.9】分割田地

script 連通 分配 mathjax cnblogs 沒有想到 -1 str 需要

Link

  https://jzoj.net/senior/#main/show/2938

Description

  地主某君有一塊由2×n個柵格組成的土地,有k個兒子,現在地主快要終老了,要把這些土地分給這些兒子。分給每個兒子的土地最小的單位是一個柵格,同時,分給同一個兒子的土地要求要相鄰連續的。地主覺得分給某個兒子的土地面積至少有一個柵格,但是具體多少可以隨意。

  請問,聰明的你,能夠算出地主一共有多少種分土地的方法嗎?也就是說要求把2*n的柵格分成k個連通區域,每個區域至少有一個柵格。

Solution

10~90分

  應該都是正解某些細節沒有處理好,或者可以打個遞歸暴力做一下,可以得到少量的分數

100分

  這道題是道很好的DP題目,準確來說是遞推,因為它有許多情況需要討論。

  我們設f[i,k,0/1]表示你選到第i列,其中分配給k個兒子,第i列兩個柵格分配給不同一個兒子為0,反之,為1。

  關鍵是很難想到轉移。

  其中有9種情況,其實應該有12種情況,因為有的,狀態一樣,但是情況不一樣。

  [1]、f[i,k,0]:=f[i,k,0]+f[i-1,k-2.0]

  [2]、f[i,k,0]:=f[i,k,0]+f[i-1,k-2,1]

  [3]、f[i,k,0]:=f[i,k,0]+f[i-1,k-1,1]*2

  [4]、f[i,k,0]:=f[i,k,0]+f[i-1,k-1,0]*2

  [5]、f[i,k,0]:=f[i,k,0]+f[i-1,k,0]

  [6]、f[i,k,1]:=f[i,k,1]+f[i1,k1,0]

  [7]、f[i,k,1]:=f[i,k,1]+f[i-1,k-1,1]

  [8]、f[i,k,1]:=f[i,k,1]+f[i-1,k,0]*2

  [9]、f[i,k,1]:=f[i,k,1]+f[i-1,k,1]

  狀態怎麽來呢?與前一列的狀態有關,具體可以分成如下9種。盜用別人的圖片

技術分享

  自己手推一下,非常容易可以的出來,故本題就迎刃而解了。沒有想到遞推如此強大。

Code

uses math;
const maxn=100000007; var n,m,i,k:longint; f:array[0..1000,-1..2000,0..2] of int64; begin readln(n,m); f[1,1,1]:=1; f[1,2,0]:=1; for i:=2 to n do for k:=1 to min(i*2,m) do begin f[i,k,0]:=(f[i,k,0]+f[i-1,k-2,0]+f[i-1,k-2,1]+f[i-1,k-1,1]*2+f[i-1,k-1,0]*2+f[i-1,k,0]) mod maxn; f[i,k,1]:=(f[i,k,1]+f[i-1,k-1,0]+f[i-1,k-1,1]+f[i-1,k,0]*2+f[i-1,k,1]) mod maxn; end; writeln((f[n,m,1]+f[n,m,0]) mod maxn); writeln(chr(26)); end.

[jzoj]2938.【NOIP2012模擬8.9】分割田地