1. 程式人生 > 實用技巧 >JZOJ【NOIP2013模擬聯考14】隱藏指令

JZOJ【NOIP2013模擬聯考14】隱藏指令

JZOJ【NOIP2013模擬聯考14】隱藏指令

題目

Description

在d維歐幾里得空間中,指令是一個長度為2N的串。串的每一個元素為d個正交基的方向及反方向之一。例如,d = 1時(數軸),串的每一個元素為左或右;d = 2時(平面),串的元素為上下左右之一;d = 3時(空間),串的元素為上下左右前後之一;d≥4時同理。
從起點出發,結月緣按照順序一個一個的執行指令S中的元素,對於每個元素,結月往該方向行走1步。圖2是一個例子,d = 2, S =→↓↑→→↓→→,|S|=2N=8。

我們認為,指令S是能夠變得幸福的,當且僅當結月執行完該指令S後能夠回到出發點。
請計算有多少種不同的指令S是能夠變得幸福的,並輸出其mod 1 000 000 007的值。兩個指令被認為不同當且僅當存在一個位置,兩個串在該處的元素不同。

Input

輸入僅一行,兩個用空格分開的非負整數d,N。

Output

輸出僅一行,僅一個整數表示能夠變得幸福的指令數mod 1 000 000 007。

Sample Input

輸入1:
2 0
輸入2:
2 1
輸入3:
2 2
輸入4:
3 1
輸入5:
3 2

Sample Output

輸出1:
1
【樣例1說明】
空指令是能夠變得幸福的。
輸出2:
4
【樣例2說明】
S1 =←→, S2 =→← , S3 =↑↓, S4 =↓↑
輸出3:
36
【樣例3說明】
如果結月緣只在一個維度上運動,也就是指令中橫與縱的方向不同時出現,那麼可能的情況有12種。如果結月緣在兩個維度上都有運動,也就是指令中左右上下同時出現,那麼有4! = 24種情況。相加後除以1 000 000 007取餘數即可得到答案36。
輸出4:
6
【樣例4說明】
結月只能在三個維度之中一個運動,每個維度對應兩種可能的能夠變得幸福的隱藏指令。故總計3*2=6。
輸出5:
90

Data Constraint

題解

題意

有一個\(d\)維空間,同時有一個長度為\(2n\)的操作序列,每個操作往某一維的正方向或反方向走一格,問多少種方案使得最後走回原點,對\(1e9+7\)取模

題解

5%

\(n=0\)時答案是1
期望得分5

30%

\(d=1\)時答案是\(C_{2n}^n\)
因為只有正方向和反方向各佔一半才能走回原點
綜上,期望得分30

60%

\(d=2\)時答案是\((C_{2n}^n)^2\)
證明如下

綜上,期望得分60

75%

\(d=3\)時答案為
\(\sum_{i=0}^n\sum_{j=0}^{n-i}C_{2n}^{2i}C_{2n-2i}^{2j}C_{2i}^iC_{2j}^jC_{2n-2i-2j}^{n-i-j}\)


證明同\(d=2\)
綜上,期望得分75

100%

考慮\(dp\)
\(f[i][j]\)表示當前到了第\(i\)維,放了\(j\)對正反方向
轉移
\(f[i][j]=\sum_{k=0}^jf[i-1][j-k]*C_{2j}^{2k}*C_{2k}^k\)
\(k\)表示當前這一維要放幾對正反
預處理組合數即可

Code

#include<cstdio>
#include<cstring>
#define mod 1000000007
using namespace std;
int n,d,t[401];
long long s,now,g[401][401],f[401][401];
int main()
{
	scanf("%d%d",&d,&n);
	if (n==0)
	{
		printf("1\n");
		return 0;	
	} 
	g[0][0]=1;
	for (int i=1;i<=2*n;++i)
		for (int j=0;j<=i;++j)
			g[i][j]=(g[i-1][j-1]+g[i-1][j])%mod;
	f[0][0]=1;
	for (int i=1;i<=d;++i)
		for (int j=0;j<=n;++j) 
			for (int k=0;k<=j;++k)
				f[i][j]=(f[i][j]+((f[i-1][j-k]*g[2*j][2*k]%mod)*g[2*k][k]%mod))%mod;
	printf("%lld\n",f[d][n]);
	return 0;
}