hrbust/哈理工oj 1126 Final Destination II【矩阵快速幂+递推】

来源:互联网 发布:香蕉网络免费频道 编辑:程序博客网 时间:2024/04/29 22:19

Final Destination IITime Limit: 1000 MSMemory Limit: 65536 KTotal Submit: 342(97 users)Total Accepted: 139(75 users)Rating: Special Judge: NoDescription

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.

Author齐达拉图题目大意:你初始的时候在第0阶台阶上,给你一个目标N阶 ,问一共有多少种上法,注意1 2 和2 1算作两种。

分析:

一道很简单的递推题目,主要是N特别大,直接跑o(N)也是一样会超时。所以我们利用公式+矩阵快速幂就能够优化时间复杂度,尤其在N特别大的时候,优化的越明显。

有关矩阵快速幂的学习大家可以去POJ 做一下3070 这里我提供题解:http://blog.csdn.net/mengxiang000000/article/details/50595065。

思路:

推出Fn=Fn-1+Fn-2+Fn-3。

然后老老实实的用草纸写下这样的方程式:

(???)X(Fn-1)=(Fn)(???) (Fn-2) (Fn-1)(???) (Fn-3) (Fn-2)如果你会矩阵乘法的话,你就一定能够算出这么些个问号都等于什么

结果为:

1 1 1

1 0 0

0 1 0

然后自己拿草纸幂两次,不难发现B.mat【0】【0】就是结果。

AC代码:

#include<stdio.h>#include<iostream>#include<string.h>using namespace std;#define mod 1000000007#define ll long long inttypedef struct Matrix{    ll mat[3][3];}matrix;matrix A,B;Matrix matrix_mul(matrix a,matrix b)//矩阵乘法{    matrix c;    memset(c.mat,0,sizeof(c.mat));    int i,j,k;    for(int i=0;i<3;i++)    {        for(int j=0;j<3;j++)        {            for(int k=0;k<3;k++)            {                c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];                c.mat[i][j]%=mod;            }        }    }    return c;}Matrix matrix_quick_power(matrix a,int k)//矩阵快速幂0.0{    matrix b;    memset(b.mat,0,sizeof(b.mat));    for(int i=0;i<3;i++)    b.mat[i][i]=1;//单位矩阵b    while(k)    {        if(k%2==1)        {            b=matrix_mul(a,b);            k-=1;        }        else        {            a=matrix_mul(a,a);            k/=2;        }    }    return b;}int main(){    int kase=0;    int t;    scanf("%d",&t);    while(t--)    {        int n;        scanf("%d",&n);        A.mat[0][0]=1;A.mat[0][1]=1;A.mat[0][2]=1;//我们通过推论得到的矩阵A        A.mat[1][0]=1;A.mat[1][1]=0;A.mat[1][2]=0;        A.mat[2][0]=0;A.mat[2][1]=1;A.mat[2][2]=0;        B=matrix_quick_power(A,n);        printf("Case %d:\n",++kase);        printf("%d\n",B.mat[0][0]);    }}






1 0
原创粉丝点击