HDU

来源:互联网 发布:js实现数组去重 编辑:程序博客网 时间:2024/06/06 03:49

题目大意:

给你一个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 1000000007using 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百度之星复赛的一道题,本来之前蓝桥杯的时候,做过一个类似的题的,当时一直想找当时的代码,结果好不容易找到了交上去还是错的,结果还是自己重写的。