版权声明:请大家斧正,如喜欢的话,为拙见点一个赞吧。 https://blog.csdn.net/qq_39897867/article/details/83240414
题目
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);
}