Problem Description
众所周知,度度熊最近沉迷于 Pokémon GO。
今天它决定要抓住所有的精灵球!
为了不让度度熊失望,精灵球已经被事先放置在一个2*N的格子上,每一个格子上都有一个精灵球。度度熊可以选择任意一个格子开始游戏,抓捕格子上的精灵球,然后移动到一个相邻的至少有一个公共点的格子上继续抓捕。
例如,(2, 2) 的相邻格子有(1, 1), (2, 1) 和 (1, 2) 等等。
现在度度熊希望知道将所有精灵球都抓到并且步数最少的方案数目。
两个方案被认为是不同,当且仅当两个方案至少有一步所在的格子是不同的。
Input
第一行为T,表示输入数据组数。
每组数据包含一个数N。
●1≤T≤100
●1≤N≤10000
Output
对每组数据输出方案数目,结果对 1 000 000 007 取模。
 Sample Input
3
1
2
3
Sample Output
2
24
96
 

一道计数问题,重点就是要做到不重不漏.

怎样步数最短呢?当然是每个格子都只经过1次啦.

然后我们注意到如果这个起点选在中间的第i列,我们就把这个格子划分成了左右两个部分

感觉就是对于某个起点然后左右两部分是之前求过的答案直接相乘,不同起点再相加就可以了,但是关键问题是我们怎样计数呢?

我们设 Bn 代表从某个角(如左上角)出发,然后走遍所有格子回到同一列的方案数目。

hdu 6146 Pokémon GO (计数)-LMLPHP

hdu 6146 Pokémon GO (计数)-LMLPHP

同样,我们设 An 代表从某个角出发,然后走遍所有格子的方案数。

hdu 6146 Pokémon GO (计数)-LMLPHP

下面我们来解释这个式子

第一项hdu 6146 Pokémon GO (计数)-LMLPHP表示从某个角开始最后回到起点的同一列的那个角

第二项hdu 6146 Pokémon GO (计数)-LMLPHP表示从某个角开始,第二步走与起点相同列的那个角,第三步我们向第二列走的时候就有两种走法了(选择直接向右或者走对角线,乘的那个2)

从第四步开始我们现在面对的问题就是hdu 6146 Pokémon GO (计数)-LMLPHP

第三项hdu 6146 Pokémon GO (计数)-LMLPHP中4可以看成2*2,

我们把前两列写成这个样子

12
34

第一个2代表走一个(1 2 3 4)和(1 4 3 2)有两种走法起点在第一列而终点在第二列

第二个2代表对于每一个到达第二列后第五步向第三列走的时候都有两种走法(向右或者走对角线)

从第六步开始时我们面对的问题就是hdu 6146 Pokémon GO (计数)-LMLPHP

我们现在来考虑下正经问题

首先有4个角,那么ans先加上hdu 6146 Pokémon GO (计数)-LMLPHP

但是如果我们起点选在中间呢?

假设我们选在了第i列,首先这一列有两个格子 所以先乘个2

现在我们可以选择先往左跑,我们可以直接向左,也可以走一个向左的对角线.再乘个2

注意往左跑完1~i-1列以后一点要跑到第i列那个"不是起点的点"否则没法往右跑,所以乘的是hdu 6146 Pokémon GO (计数)-LMLPHP

现在我们又回到了第i列,现在我们向右跑,又有两种情况,直接向右,向右的对角线 再乘个2

现在我们到了i+1列对于右半部分(i+1~n)我们只要跑完就行了,我们不关心终点所以乘hdu 6146 Pokémon GO (计数)-LMLPHP

这样一开始向左跑就是hdu 6146 Pokémon GO (计数)-LMLPHP,一开始向右跑自然是hdu 6146 Pokémon GO (计数)-LMLPHP

 #include <bits/stdc++.h>

 using namespace std;
typedef long long ll;
const int maxn = ;
const ll mod = 1e9+;
ll a[maxn],b[maxn];
void init()
{
b[]=;
for (int i=;i<maxn;++i){
b[i] = (b[i-]*)%mod;
}
a[] = ;
a[] = ;
for (int i=;i<maxn;++i)
a[i] = (b[i]%mod+(*a[i-]%mod)+(*a[i-])%mod)%mod;
}
int n;
int main()
{
init();
int T;
scanf("%d",&T);
while (T--){
scanf("%d",&n);
if (n==){
printf("%d\n",);
}
else{
ll ans = ;
ans = (a[n]*)%mod;
for (int i=;i<n;++i){
ans = (ans+*( ( ( (*b[i-])%mod) *( (*a[n-i])%mod ) + ( (*a[i-])%mod) *( (*b[n-i])%mod ) )%mod )%mod)%mod;
}
printf("%lld\n",ans);
}
}
return ;
}
05-21 16:29