题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6146
先考虑从(1,1)开始走的方案数,有如下几种情况
那么从第一列出发的方案数就可算了,乘以2即可
令
gi=2i−1
则方案数
pi=2∗fi−1+4∗fi−2+gi+1
但是第一种情况中,起始点和终点在同一列,会出现一些重复
所以我们实际要求出一个
fi=pi−gi=2∗fi−1+4∗fi−2+gi
即可
可以发现,任何一种方案,都可以由第一种情况和这几种情况拼起来
所以
ans=4∗fn+8∗∑i=2n−1gi−1∗fn−i+8∗∑i=2n−1fi−1∗gn−i
注意取模的一些问题
贴代码
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=10005,P=1000000007;
int f[maxn],g[maxn];
int ans,Q,n;
int main(){
// freopen("6146.in","r",stdin);
// freopen("6146.out","w",stdout);
scanf("%d",&Q);
f[1]=1;f[2]=6;
g[1]=1;g[2]=2;
for (int i=3;i<=maxn;i++){
g[i]=(g[i-1]*2)% P;
f[i]=(2ll*ll(f[i-1])+4ll*ll(f[i-2]))%P;
f[i]=(f[i]+g[i])%P;
}
for (int t=1;t<=Q;t++){
scanf("%d",&n);
if (n==1){printf("%d\n",2);continue;};
ans=0;
for (int i=2;i<=n-1;i++)ans=(ll(ans)+8ll*ll(g[i-1])*ll(f[n-i])%P+8ll*ll(g[n-i])*ll(f[i-1])%P)%P;
ans=(ll(ans)+4ll*ll(f[n]))%P;
printf("%d\n",ans);
}
return 0;
}
【写的有漏洞的,欢迎路过大神吐槽】
2017/08/24 20:44:29
Ending.