[JZOJ 2938] 分割田地 {動態規劃}
阿新 • • 發佈:2018-12-16
題目
Description
地主某君有一塊由2×n個柵格組成的土地,有k個兒子,現在地主快要終老了,要把這些土地分給這些兒子。 分給每個兒子的土地最小的單位是一個柵格,同時,分給同一個兒子的土地要求要相鄰連續的。 地主覺得分給某個兒子的土地面積至少有一個柵格,但是具體多少可以隨意。 請問,聰明的你,能夠算出地主一共有多少種分土地的方法嗎?也就是說要求把2*n的柵格分成k個連通區域,每個區域至少有一個柵格。
Input
包含兩個正整數n和k。
Output
包含一個整數,為可以分土地的方法數模100000007。
結題思路
- 設表示已經取了第行,分為個連通區域,狀態為或時的總方案數
- 對於狀態,我們有如下定義:
- 、狀態表示第行的兩個柵格分屬於兩個不同的連通區域
- 、狀態表示第行的兩個柵格屬於同一個連通區域
程式碼
#include<cstdio>
using namespace std;
const int myself=100000007;
int n,k,f[1005][2501][2];
inline int minn(int x,int y){return x<y?x:y;}
inline int read()
{
int p=0; char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') p=(p<<3)+(p<<1)+c-'0',c=getchar();
return p;
}
int main()
{
n=read(),k=read();
f[1][2][0]=f[1][1][1]=1;
for (int i=2;i<=n;i++)
for (int j=1;j<=minn(i<<1,k);j++)
{
f[i][j][0]+=f[i-1 ][j-2][0]+f[i-1][j-2][1]+(f[i-1][j-1][0]<<1)+(f[i-1][j-1][1]<<1)+f[i-1][j][0];
f[i][j][1]+=f[i-1][j-1][0]+f[i-1][j-1][1]+(f[i-1][j][0]<<1)+f[i-1][j][1];
f[i][j][0]%=myself;
f[i][j][1]%=myself;
}
printf("%d",(f[n][k][1]+f[n][k][0])%myself);
}