【NOIP2013模拟联考14】隐藏指令

题目大意

解题思路

要想回到原点,走一个方向后必定会再走一个相反的方向。

先算算(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));
}
原文地址:https://www.cnblogs.com/nibabadeboke/p/13973334.html