zoukankan      html  css  js  c++  java
  • 蓝桥杯 算法提高 递推求值

    题目如下:

    问题描述
      已知递推公式:

      F(n, 1)=F(n-1, 2) + 2F(n-3, 1) + 5,

      F(n, 2)=F(n-1, 1) + 3F(n-3, 1) + 2F(n-3, 2) + 3.

      初始值为:F(1, 1)=2, F(1, 2)=3, F(2, 1)=1, F(2, 2)=4, F(3, 1)=6, F(3, 2)=5。
      输入n,输出F(n, 1)和F(n, 2),由于答案可能很大,你只需要输出答案除以99999999的余数。
    输入格式
      输入第一行包含一个整数n。
    输出格式
      输出两行,第一行为F(n, 1)除以99999999的余数,第二行为F(n, 2)除以99999999的余数。
    样例输入
    4
    样例输出
    14

    21
    数据规模和约定
      1<=n<=10^18。
    -----分割线-----
      在拿到此题后,就知道这题应该是矩阵快速幂,但是因为以前只做过简单的斐波那契数列的矩阵快速幂,所以完全不知道这题该怎么构造矩阵,后来翻了百度上的很多博客。简单来说,就是找到一个矩阵A满足:x(n-1)*A=x(n)。当然,此题不同于一般的“x(n)、x(n-1)”。要做如下构造:
      [f(n-1,1),f(n-1,2),f(n-2,1),f(n-2,2),f(n-3,1),f(n-3,2),5,3]*A=[f(n,1),f(n,2),f(n-1,1),f(n-1,2),f(n-2,1),f(n-2,2),5,3]
      即把前三项当做x(n-1),后一项以及前三项的后两项当做x(n),易知矩阵为8阶矩阵,具体见代码:
    #include<stdio.h>
    #define max 99999999
    #define ll long long int
    typedef struct Matrix
    {
        ll m[8][8];
    }mat;
    mat multi(mat x,mat y,int a,int b,int c)
    {
        int i,j,k;
        mat z;
        for(i=0;i<8;i++)
            for(j=0;j<8;j++)
                z.m[i][j]=0;
        for(i=0;i<a;i++)
            for(j=0;j<c;j++)
                for(k=0;k<b;k++)
                    z.m[i][j]=(z.m[i][j]+(x.m[i][k]*y.m[k][j])%max)%max;
        return z;
    }
    int main()
    {
        ll n,v1,v2,i;
        mat A={ 0,1,1,0,0,0,0,0,
                1,0,0,1,0,0,0,0,
                0,0,0,0,1,0,0,0,
                0,0,0,0,0,1,0,0,
                2,3,0,0,0,0,0,0,
                0,2,0,0,0,0,0,0,
                1,0,0,0,0,0,1,0,
                0,1,0,0,0,0,0,1
                                };
        mat E={ 1,0,0,0,0,0,0,0,
                0,1,0,0,0,0,0,0,
                0,0,1,0,0,0,0,0,
                0,0,0,1,0,0,0,0,
                0,0,0,0,1,0,0,0,
                0,0,0,0,0,1,0,0,
                0,0,0,0,0,0,1,0,
                0,0,0,0,0,0,0,1,
                                };
        ll s[8]={6,5,1,4,2,3,5,3};
        scanf("%I64d",&n);
        if(n==1)
            printf("2
    3");
        if(n==2)
            printf("1
    4");
        if(n==3)
            printf("6
    5");
        if(n>=4)
        {
            n-=3;
            while(n)
            {
                if(n%2)
                    E=multi(E,A,8,8,8);
                n/=2;
                A=multi(A,A,8,8,8);
            }
            v1=0;
            v2=0;
            for(i=0;i<8;i++)
            {
                v1=(v1+(s[i]*E.m[i][0])%max)%max;
                v2=(v2+(s[i]*E.m[i][1])%max)%max;
            }
            printf("%I64d
    %I64d",v1,v2);
        }
        return 0;
    }
  • 相关阅读:
    Jersey 2.x 运行项目
    Jersey 2.x 探索新建的工程
    Jersey 2.x 从Maven Archetype 创建一个新项目
    Jersey 2.x 服务器端应用支持的容器
    Jersey 2.x JDK 上的客户端应用
    Jersey 2.x 基于 Servlet 的服务器端应用
    =面试题:java面试基本方向 背1 有用 项目二技术学完再看
    面试题:项目开发经验总结 框架 比较难的问题 可以找一下有用
    面试题: !=!=未看
    面试题:大公司面试题 !=!=未看
  • 原文地址:https://www.cnblogs.com/search-the-universe/p/holiday-4.html
Copyright © 2011-2022 走看看