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

 

 

你可能感兴趣的:(T)