zoukankan      html  css  js  c++  java
  • 蓝桥杯算法提高 递推求值 【矩阵快速幂】

      算法提高 递推求值  
    时间限制:1.0s   内存限制:256.0MB
       
    锦囊1
     
    锦囊2
     
    锦囊3
     
    问题描述
      已知递推公式:

      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
     
     
    第一次做矩阵快速幂的题目开始做的一塌糊涂,看到了这篇文章的启发http://www.cnblogs.com/frog112111/archive/2013/05/19/3087648.html解释的很明白。
    题目分析:
    构造一个1×8的矩阵[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]
    ,根据递推关系,可以通过乘以一个8×8的矩阵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],算出矩阵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

    之后再利用矩阵快速幂的方法得到结果。

    AC代码:

    #include <iostream>
    #include <cstring>
    
    using namespace std;
    struct matrix
    {
        long long a[8][8];
    };
    matrix multiply(matrix x,matrix y,int m,int n,int s)//m*s   s*n  矩阵相乘
    {
        matrix temp;
        memset(temp.a,0,sizeof(temp.a));
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                    for(int k=0;k<s;k++)
                        temp.a[i][j]=(temp.a[i][j]+(x.a[i][k]*y.a[k][j])%99999999)%99999999;
        return temp;
    }
    int main()
    {
    
        matrix temp={
                           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
                          };
        matrix res;
        long long f[8]={6,5,1,4,2,3,5,3},sum1,sum2,n;
        memset(res.a,0,sizeof(res.a));
        for(int i=0;i<8;i++)
            res.a[i][i]=1;
        cin>>n;
        if(n==1)
            cout<<"2"<<endl<<"3"<<endl;
        if(n==2)
            cout<<"1"<<endl<<"4"<<endl;
        if(n==3)
            cout<<"6"<<endl<<"5"<<endl;
        if(n>=4)
        {
        n=n-3;
        while(n)//矩阵快速幂
        {
            if(n&1)
            {
                res=multiply(res,temp,8,8,8);
            }
            n>>=1;
            temp=multiply(temp,temp,8,8,8);
        }
        sum1=sum2=0;
        for(int i=0;i<8;i++)
        {
            sum1=(sum1+(f[i]*res.a[i][0])%99999999)%99999999;
            sum2=(sum2+(f[i]*res.a[i][1])%99999999)%99999999;
        }
        cout<<sum1<<endl<<sum2<<endl;
        }
    
        return 0;
    }
  • 相关阅读:
    tableView操作数据持久化
    9.0banb以前和9.0以后版本后JSON解析
    数据持久化存储回顾
    解决Xcode会出现的问题
    iview-cli 项目、iView admin 代理与跨域问题解决方案
    将变量做为一个对象的key,push新增进一个数组
    页面加载速度优化的建议
    vue中渲染页面,动态设置颜色
    e.currentTarget与e.target
    iview中tree的事件运用
  • 原文地址:https://www.cnblogs.com/asuml/p/6517451.html
Copyright © 2011-2022 走看看