【NOIP2013模拟联考14】隐藏指令
题目大意

解题思路
要想回到原点,走一个方向后必定会再走一个相反的方向。
先算算\(d = 1\)的情况,有\(2 * n\)个位置,选\(n\)个放正方向,其余为负方向,方案数为\(\tbinom{2n}{n}\)
同理可得\(d = 2\)时,方案数为\(\tbinom{2n}{k} \tbinom{2n - k}{k} \tbinom{2n - 2k}{n - k}\)
\(d = 3\)时,方案数为\(\tbinom{2n}{k_1} \tbinom{2n - k_1}{k_1} \tbinom{2n - 2k_1}{k_2} \tbinom{2n - 2k_1 - k_2}{k_2} \tbinom{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\n",dfs(n,1));
}

浙公网安备 33010602011771号