题目大意
解题思路
要想回到原点,走一个方向后必定会再走一个相反的方向。
先算算(d = 1)的情况,有(2 * n)个位置,选(n)个放正方向,其余为负方向,方案数为( binom{2n}{n})
同理可得(d = 2)时,方案数为( binom{2n}{k} binom{2n - k}{k} binom{2n - 2k}{n - k})
(d = 3)时,方案数为( binom{2n}{k_1} binom{2n - k_1}{k_1} binom{2n - 2k_1}{k_2} binom{2n - 2k_1 - k_2}{k_2} binom{2(n - k_1 - k_2)}{n - k_1 - k_2})
......
所以,我们可以打一个记忆化搜索来枚举(k)
(Code)
#include<cstdio>
#include<cstring>
using namespace std;
const int P = 1e9 + 7;
long long f[405][405],c[405][405];
int d,n;
long long dfs(int s,int x)
{
if (x >= d) return c[s << 1][s];
if (f[s][x] != -1) return f[s][x];
long long res = 0;
for (int i = 0; i <= s; i++)
res = (res + c[s << 1][i] * c[(s << 1) - i][i] % P * dfs(s - i,x + 1) % P) % P;
f[s][x] = res;
return res;
}
int main()
{
scanf("%d%d",&d,&n);
for (int i = 0; i <= n << 1; i++) c[i][0] = 1;
for (int i = 1; i <= n << 1; i++)
for (int j = 1; j <= i; j++)
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % P;
memset(f,255,sizeof(f));
printf("%lld
",dfs(n,1));
}