题目大意:

给你一个2*n的方格,从任意一个格可以到达它周围的任意一个格子(至少有一个角相连接),现在让你从任意一个点开始,不重复地遍历所有格子。问你一共有多少种遍历方法。

分析:

确定状态:

a[i]表示从左上角开始,遍历一个长度为 2*i 的方格,并最终回到左下角的走法数;
b[i]表示从左上角开始,便利一个长度为 2*i 的方格的走法数;

状态转移方程:

a[i]=a[i1]2;
b[i]=a[i]+2b[i1]+4b[i2]

边界条件:

a[1]=1;
b[1]=1;b[2]=6;

最后只要枚举一遍起始点,然后分步乘法,分类加法就好了。

代码:

#include<bits/stdc++.h>
#define maxn 10050
#define mod 1000000007
using namespace std;
int t,n;

long long int a[maxn];
long long int b[maxn];

void init()
{
    a[1]=1;
    b[1]=1;
    b[2]=6;
    for(int i=2;i<maxn;i++)
    {
        a[i]=a[i-1]<<1;
        a[i]%=mod;
    }
    for(int i=3;i<maxn;i++)
    {
        b[i]=(b[i-2]<<2)+a[i]+(b[i-1]<<1);
        b[i]%=mod;
    }
}
long long int fx(int x)
{
    long long int ans=0;
    ans+=a[x]*b[n-x];
    ans%=mod;
    ans<<=2;
    return ans;
}
int main()
{
    scanf("%d",&t);
    init();
    while(t--)
    {
        scanf("%d",&n);
        if(n==1)
        {
            printf("2\n");
            continue;
        }
        long long int sum=0;
        for(int i=2;i<n;i++)
        {
            sum+=fx(i);
            sum%=mod;
        }
        sum+=(b[n]<<1);
        sum<<=1;
        sum%=mod;
        printf("%I64d\n",sum);
    }

}

注:2017百度之星复赛的一道题,本来之前蓝桥杯的时候,做过一个类似的题的,当时一直想找当时的代码,结果好不容易找到了交上去还是错的,结果还是自己重写的。