简单递推公式转换矩阵求解

对于许多递推题目,由于数据范围太大直接循环写会爆掉,这时首先想到的就是矩阵优化,把递推式转换成01矩阵通过快速幂优化。

比如最简单的斐波纳挈,如果n非常大,循环递推肯定是不合适的,那么可以考虑下面的公式  (f[n],f[n-1])=(f[n-1],f[n-2])*A; 这里的A是一个01矩阵,此时的A={1,1,1,0} 2*2的矩阵,    可想而知 f[3] = A的n-2次幂*(f[2],f[1]);   形如斐波纳挈的递推公式转换矩阵都很简单, 顺便附上POJ3070的 斐波纳挈转矩阵快速幂的代码

#include<cstdio>
#include<cstring>
#include<iostream>
#define MOD 10000
using namespace std;

struct mac
{
    int frob[2][2];
}pri,unit;

mac power(mac x,mac y)
{
    mac temp;
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        {
            temp.frob[i][j]=0;
            for(int k=0;k<2;k++)
            {
                temp.frob[i][j]=(temp.frob[i][j]+x.frob[i][k]*y.frob[k][j])%MOD;
            }
        }
    }
    return temp;
}
void eachother(int n)
{
    pri.frob[0][0]=pri.frob[0][1]=pri.frob[1][0]=1;
    pri.frob[1][1]=unit.frob[0][1]=unit.frob[1][0]=0;
    unit.frob[0][0]=unit.frob[1][1]=1;
    while(n)
    {
        if(n&1)
        {
            unit = power(unit,pri);
        }
        pri = power(pri,pri);
        n >>= 1;
    }
    printf("%d\n",unit.frob[0][1]);
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==-1) break;
        if(n==0)
        {
            printf("0\n");
            continue;
        }
        if(n==1||n==2)
        {
            printf("1\n");
            continue;
        }
        eachother(n);
    }
    return 0;
}
时间: 2024-11-07 06:55:49

简单递推公式转换矩阵求解的相关文章

28 利用平面对应关系求解RT空间转换矩阵

0 引言 问题背景:给定CAD模型与点云的情况下,基于CAD比对实现对实测点云的尺寸测量是三维测量技术中一种常用的思路.该思路的关键问题在于需要精确求解CAD模型与点云之间的空间转换矩阵.采用ICP(迭代最近邻点算法)的变种,将基于点-点对应关系的算法拓展为基于平面-平面的算法.当前,基于二次开发技术求解出了CAD模型中的所有平面,并且基于点云PCL库中的生长聚类算法(regionGrowing做分割,RANSAC对平面方程进行拟合)提取出了典型平面,因此希望通过平面-平面对应关系解出二者之间的

简单螺旋打印矩阵 - 直接, 好理解

打印螺旋矩阵的一种简单办法 , C 语言实现 #include <stdio.h> #define N 30 static int val = 10; int arr[N][N]; void print_row(int row_cur, int col_start, int col_end, int left_to_right){ int col_cur = col_start; if( col_start < 0 || col_end < 0) return; if( left_

一个简单的转换字母大小写的方法

[这里我们将要介绍一个最简单也最快速的转换字母大小写的方法,提示:使用位技巧] [以下代码用C语言编写] 在编程的时候我们经常遇到需要转换字母大小写的情况,有时候就是这个问题,有时候是为了解决其它问题.大家应该能想到一些方法.我将要介绍一种最优美的方法,也就是用比特技巧解决问题. 这个技巧非常简单,就是用大小写字母的ASCII值来转换他们(大小写字母ASCII值相差32).将字母的ASCII值的第5位(或者第6位,取决于你怎么数)进行异或运算,看下面: a = 01100001 A = 0100

Eigen学习之简单线性方程与矩阵分解

Eigen提供了解线性方程的计算方法,包括LU分解法,QR分解法,SVD(奇异值分解).特征值分解等.对于一般形式如下的线性系统: 解决上述方程的方式一般是将矩阵A进行分解,当然最基本的方法是高斯消元法. 先来看Eigen 官方的第一个例程: 1 #include <iostream> 2 #include <Eigen/Dense> 3 4 using namespace std; 5 using namespace Eigen; 6 7 int main() 8 { 9 Mat

简单数论之矩阵构造

其实矩阵构造就是对公式的化简,最后运用矩阵快速幂求值 下面来看一题 Everybody knows Fibonacci numbers, now we are talking about the Tribonacci numbers: T[0] = T[1] = T[2] = 1; T[n] = T[n - 1] + T[n - 2] + T[n - 3] (n >= 3)Given a and b, you are asked to calculate the sum from the ath

POJ 2115 简单的模线性方程求解

简单的扩展欧几里得题 这里 2^k 不能自作聪明的用 1<<k来写 , k >= 31时就爆int了 , 即使定义为long long 也不能直接这样写 后来老老实实 for(int i=1 ; i<=k ; i++) bb = bb*2; 才过了= = 1 #include <cstdio> 2 #include <cstring> 3 4 using namespace std; 5 #define ll long long 6 ll ex_gcd(ll

hdu2604 递推转换矩阵快速幂

刚开始还以为用位运算与或几下几个循环就搞定了,算着算着发现不行........ 还是一种固定的切题角度,我假设有长度为n,总的排列数位f(n),怎么算他呢?从后往前考虑,因为大多数情况,都是用前面的结果推后面的结果, 那么当第n位是m的时候,如果我知道f(n-1)等于多少,那么f(n-1)的排列+加一个m是不是就是f(n)的一部分解了?  对吧,以此类推,   当第n位为f的时候,可是fff,fmf不能连着 那是不是就剩下ffm,fmm的情况了,对于前者ffm,由于不能凑成ffmf的情况,所以只

hdu 1005 根据递推公式构造矩阵 矩阵快速幂

f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. Sample Input1 1 3 //a b n1 2 100 0 0 Sample Output25 矩阵A  * 矩阵B  = 矩阵C a b        f(n-1)     f(n) 1 0        f(n-2)    f(n-1) 1 # include <iostream> 2 # include <cstdio> 3 # inclu

python实现简单的并行矩阵乘法

本文采用的矩阵乘法方式是利用一个矩阵的行和二个矩阵的列相乘时不会互相影响.假设A(m,n)表示矩阵的m行,n列.那么C(m,m)=A(m,n) B(n,m) :计算C矩阵时候分解成:process-1:C(1,1) = A(1,:) B(:,1) process-2:C(1,2) = A(1,:) * B(:,2) .......... process-mC(m,m) = A(m,:) * B(:,m) 实现源码:import multiprocessing #导入多进程模块,实现多进程impo