【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));
}
posted @ 2020-11-14 15:30  RiverSheep  阅读(132)  评论(0)    收藏  举报