矩阵快速幂 小澳的坐标系

来源:互联网 发布:wincc软件在线监控 编辑:程序博客网 时间:2024/04/30 15:31

矩阵快速幂

矩阵快速幂一般是为了求解递推问题
eg:菲波那切数列

关于矩阵快速幂,可以参见这里AND这里

2. 小澳的 坐标系

(coordinate.cpp/c/pas )

【题目描述】

小澳者表也,数学者景也,表动则景随矣。小澳不喜欢数学,可数学却待小澳如初恋,小澳睡觉的时候也不放过。小澳的梦境中出现了一个平面直角坐标系,自原点,向四方无限延伸。小澳在坐标系的 原点,他可以 向上、向左或者向右走。他可以走 n 步, 但不能经过相同的点。小澳想知道他有多少种走法。

【输入格式】

输入文件名为 coordinate.in。输入文件仅第一行一个正整数 n,表示小澳可以走的步数。

【输出格式】

输出文件名为 coordinate.out。输出文件共一行,输出一个正整数,表示答案(对 10^9+7 取模)。

【输入输出样例 1 】

in:2

out:7

【输入输出样例 1 说明】

从(0,0)出发走 2 步,共 7 种走法:(0,0)->(0,1)->(0,2)(0,0)->(0,1)->(1,1)(0,0)->(0,1)->(-1,1)(0,0)->(1,0)->(2,0)(0,0)->(1,0)->(1,1)(0,0)->(-1,0)->(-2,0)(0,0)->(-1,0)->(-1,1)

【输入输出样例 2 】

in:3

out:17

【数据规模与约定 】

测试点编号  n1~2  n<=103~4  n<=1005~6  n<=10007~8  n<=10^69~10  n<=10^9

Solution:

做这题的时候先写了一个走迷宫的暴力DFS,找到递推公式
//DFS暴力#include<cstdio>#define LL long long#define mod 100000using namespace std;int n,cnt;int map[2002][2009];int u[3]={0,1,0},v[3]={1,0,-1};bool inmap(int a,int b){    return a>=1 && a<=n+1 && b>=1 && b<=2*n+1;}void DFS(int x,int y,int t){    int i;    if(t==n){        cnt++;        if(cnt==mod) cnt=0;        return;    }    for(i=0;i<3;i++){        int xx=x+u[i],yy=y+v[i];        if(!map[xx][yy] && inmap(xx,yy)){            map[xx][yy]=1;            DFS(xx,yy,t+1);            map[xx][yy]=0;        }    }}int main(){    freopen("coordinate.in","r",stdin);    freopen("coordinate.out","w",stdout);    scanf("%d",&n);    map[1][n+1]=1;    DFS(1,n+1,0);    printf("%d",cnt);    return 0;}
十以内可以解决了(20分)

然后将1~10内的解输出来找到递推关系


矩阵快速幂之所以要用,是因为它确实求递推式的时候很快

一般递推:

//SLOW#include<cstdio>#define LL long long#define mod 1000000007using namespace std;int n;void solve(){    if(n==1) {        printf("3\n");        return;    }    if(n==2){        printf("7\n");        return;    }    LL f1=3,f2=7,f3;    int i;    for(i=3;i<=n;i++){        f3=2*f2+f1;        f3%=mod;        f1=f2;f2=f3;    }    printf("%I64d",f3%mod);}int main(){    freopen("coordinate.in","r",stdin);    freopen("coordinate.out","w",stdout);    scanf("%d",&n);    solve();    return 0;}

矩阵快速幂:

//FAST#include<cstdio>#define LL long long#define mod 1000000007int n;struct M{    LL map[3][3];};M s;M work(M x,M y){    int i,j,k;    M ans;    ans.map[1][1]=ans.map[1][2]=ans.map[2][1]=ans.map[2][2]=0;    for(i=1;i<=2;i++){        for(j=1;j<=2;j++){            for(k=1;k<=2;k++){                ans.map[i][j]+=x.map[i][k]*y.map[k][j];            }            ans.map[i][j]%=mod;        }    }    return ans;}void solve(){    M tmp;    n-=2;    tmp.map[1][1]=tmp.map[0][2]=0;tmp.map[1][2]=1;tmp.map[2][1]=1;tmp.map[2][2]=2;    while(n){        if(n&1){            s=work(tmp,s);        }        tmp=work(tmp,tmp);        n>>=1;    }    printf("%d",s.map[2][1]%mod);}int main(){    freopen("coordinate.in","r",stdin);    freopen("coordinate.out","w",stdout);    scanf("%d",&n);    if(n==1){        printf("3\n");return 0;    }    if(n==2){        printf("7\n");return 0;    }    s.map[1][1]=3;s.map[2][1]=7;    solve();    return 0;}
0 0
原创粉丝点击