NBUT比赛 方格规律递推题

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=26901#problem/A

 

题意:有一个 2*n的格子里,你可以选择任意一个格子作为起点,你可以朝着相邻的8个格子行走且一个格子只能被走一次. 问把所有格子都走一遍有多少种方法!

思路:

n=1,n=2的时候特判一下。

n>2的时候就要分两种情况考虑了,第一种是对旁边四个角考虑,另外一种是对中间的考虑。

开一个b[i]数组表示每个当n为i时顶角有多少种走法, c[i]表示中间的格子总共有多少种走法。

对顶角分析:四个顶角等价,只需对左上角一个分析即可。

有三种走法:1、从起点开始,每列只走一格,再绕回来。则有2^(i-1)种走法

                  2、起点开始,往右或者右下走再回叉一下,再走的话就变成了另外一种顶角走法,则有4*b[i-2]种。

                  3、起点开始往下走一次,再往右边走,则右边成了一种顶角走法,有2*b[i-1]种。

  所以顶角的走法有:b[i]=2^(i-1)+4*b[i-2]+2*b[i-1];

对中间点分析:中间点有左右两个方向的走法,要两者加起来。

这里要注意的是中间点的起点肯定不能一开始就往下(往上)走,那样无法走,所以只能一直往一个方向选择走,遇见顶角之后折回来到达起点的的下面(上面)之后,再往下走就变成了顶角的走法。

不错的递推规律题,赞一个。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <map>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <cstring>
 7 using namespace std;
 8 
 9 typedef long long lld;
10 const int maxn=1005;
11 const lld mod=1000000007;
12 lld a[maxn], b[maxn], c[maxn], dp[maxn];
13 
14 void init()
15 {
16     memset(c,0,sizeof(c));
17     dp[1]=2, dp[2]=24;
18     a[0]=1;
19     b[1]=1, b[2]=6;
20     for(int i=1; i<maxn; i++)
21         a[i]=2*a[i-1]%mod;
22     for(int i=3; i<maxn; i++)
23     {
24         b[i]=(a[i-1]+(2*b[i-1]%mod+4*b[i-2]%mod)%mod)%mod;
25     }
26     for(int i=3; i<maxn; i++)
27     {
28         for(int j=1; j<=i-2; j++)
29         {
30             lld tp=((a[j]*4%mod)*b[i-j-1]%mod+(a[i-j-1]*4%mod)*b[j]%mod)%mod;
31             c[i]=(c[i]+tp)%mod;
32         }
33     }
34     for(int i=3; i<maxn; i++)
35     {
36          dp[i]=(c[i]+4*b[i])%mod;
37     }
38 }
39 
40 int main()
41 {
42     init();
43     int n;
44     while(~scanf("%d",&n))
45     {
46         cout << dp[n] <<endl;
47     }
48     return 0;
49 }
View Code

 

 

转载于:https://www.cnblogs.com/kane0526/p/3209094.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值