Description

JiaoZhu likes going on adventure! One day, he walks into a big castle, and there is an unique stairway. JiaoZhu finds a board ,it says “The one who want to go upstairs only can go three steps the most once, meaning that you can go 1 or 2 or 3 steps once!”. Now, we have a problem, can you tell me the number of ways to go to the destination? If you can’t ,death is the only choice

In the beginning, you are in the 0th step. 

Input

First input a integer T(T<50), represent the number of case.

Each case ,the input will consist only a positive integer n (0<=n<=1000000000), represent the nth steps you want to go to..

Output

Order the sample output format to output.

Line 1,print the Case k.

Line 2,print one integer represent the number of ways to go to nth steps.(MOD 1000000007)

Sample Input

2

1

2

Sample Output

Case 1:

1

Case 2:

2

Hint

When n=2,you can go one step once to go to 2th ,or go 2 steps once to 2th,so the answer is 2.

给一个n代表你想去第n个台阶,求出有多少种不同的走法,最后对1000000007取余。上台阶时你一步可以走1个台阶,或一次走2个台阶,或一次走3个台阶。

递推公式a(n)=a(n-1)+a(n-2)+a(n-3),当然在这个题中我们确实用了递推公式,但是却不能直接开一个数组,因为n太大数组开不了这个长度,并且循环起来会超时,

所以我们用矩阵来求。

我们举一个例子来模拟一下用矩阵的递推原理的过程

 

定义stairs2矩阵为  a[n+3]   a[n+2]   a[n+1]                       另一个stairs1矩阵  a[n+2]  a[n+1]  a[n]                矩阵的系数coeff   

                                      7            4             2                                                                     4          2         1                                               1        1        0

                                      0            0            0                                                                      0          0         0                                               1        0        1  

                                      0            0            0                                                                      0          0         0                                               1        0        0

由矩阵求法知要想得到stairs2,是用stairs1*coeff ,而在stairs2中,下标为[0][0]的就是我们所求。

快速幂:求a的b次方时可直接用:

int res=1;

while(b)

{     if(b&1) //判断b是否为奇数;

             res=a*res;

     a=a*a;

     b/=2;

}

return res;

 


#include <iostream>
using namespace std;
#define mod 1000000007
void mul(long long b[][3],long long a[][3])
{
    int i,j,k;
    long long c[3][3]={0};
    for(i=0;i<3;i++)   //矩阵的乘法运算,结果用c[][]来存
        for(j=0;j<3;j++)
         for(k=0;k<3;k++)
           c[i][j]=c[i][j]+((b[i][k]%mod)*(a[k][j]%mod))%mod;
    for(i=0;i<3;i++)   //将结果返回给b[][]
      for(j=0;j<3;j++)
        b[i][j]=c[i][j]%mod;    //这一步必须要对c[][]取余后再付给b[][],否则会出现结果错误。
}
void output(long long n,long long b[][3],long long a[][3])
{
    while(n) //矩阵的快速幂求法
    {
        if(n&1)
           mul(b,a);
        mul(a,a);
        n=n/2;
    }
    cout<<b[0][0]<<endl;
}
int main()
{
    int T,k=1;
    cin>>T;
    while(T--)
    {
        long long n;
        cin>>n;
        long long stairs[3][3]={4,2,1,0,0,0,0,0,0};
        long long coeff[3][3]={1,1,0,1,0,1,1,0,0}; //矩阵的系数
        cout<<"Case "<<k++<<":"<<endl;
        if(n==0||n==1)
            cout<<"1"<<endl;
        else if(n==2)
            cout<<"2"<<endl;
        else
            output(n-3,stairs,coeff);
    }
    return 0;
}

 

posted on 2014-10-20 18:10  星斗万千  阅读(132)  评论(0编辑  收藏  举报