算法分析中递推式的一般代数解法 张洋

http://blog.codinglabs.org/articles/linear-algebra-for-recursion.html

另介绍一种算法

Berlekamp-Massey算法,常简称为BM算法,是用来求解一个数列的最短线性递推式的算法。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-7;
const int maxn = 1e5 + 5;
vector<double> ps[maxn];
int fail[maxn];
double x[maxn], delta[maxn];
int n;
int pn;
/*
前提:必须符合线性递推,如:
fib: 1 1 2 3 5 8 13 21 34 55 89
*/
int main()
{
    while (~scanf("%d", &n)) // n 项
    {
        pn = 0;
        for (int i = 1; i <= n; i++)
        {
            scanf("%lf", &x[i]); //前 n项
        }
        for (int i = 1; i <= n; i++)
        {
            double dt = -x[i];
            for (int j = 0; j < (int)ps[pn].size(); j++)
            {
                dt += x[i - j - 1] * ps[pn][j];
            }
            delta[i] = dt;
            if (fabs(dt) <= eps) continue;
            fail[pn] = i;
            if(!pn)
            {
                ps[++pn].resize(1);
                continue;
            }
            vector<double>&ls = ps[pn - 1];
            double k = -dt / delta[fail[pn - 1]];
            vector<double> cur;
            cur.resize(i - fail[pn - 1] - 1);
            cur.push_back(-k);
            for(int j = 0; j < (int)ls.size(); j++)
            {
                cur.push_back(ls[j] * k);
            }
            if((int)cur.size() < (int)ps[pn].size())
            {
                cur.resize(ps[pn].size());
            }
            for(int j = 0; j < (int)ps[pn].size(); j++)
            {
                cur[j] += ps[pn][j];
            }
            ps[++pn] = cur;
        }
        int len = (int)ps[pn].size();
        std::cout << "f[i]=" ;
        for (int i = 0; i < len; i++)
        {
            if(ps[pn][i] > 0 && i > 0)std::cout << "+";
            if(ps[pn][i]==0)continue;
            printf("%g*f[i-%d]", ps[pn][i], i+1);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/polya/p/9711038.html

时间: 2024-10-30 15:54:24

算法分析中递推式的一般代数解法 张洋的相关文章

51nod1149 Pi的递推式

基准时间限制:1 秒 空间限制:131072 KB 分值: 640 F(x) = 1 (0 <= x < 4) F(x) = F(x - 1) + F(x - pi) (4 <= x) Pi = 3.1415926535..... 现在给出一个N,求F(N).由于结果巨大,只输出Mod 10^9 + 7的结果即可. Input 输入一个整数N(1 <= N <= 10^6) Output 输出F(N) Mod 10^9 + 7 Input示例 5 Output示例 3 数学问

Python的递推式构造列表(List comprehension)

介绍 我们在上一章学习了“Lambda 操作, Filter, Reduce 和 Map”, 但相对于map, filter, reduce 和lamdba, Guido van Rossum更喜欢用递推式构造列表(List comprehension).在这一章我们将会涵盖递推式构造列表(List comprehension)的基础功能. 递推式构造列表(List comprehension)是在Python 2.0中添加进来的.本质上,它是一种数学家用来实现众所周知标记集合的Python方式

一只青蛙从第一级台阶跳到第n级,每次可以跳任意级,共有多少种跳法,并写出递推式

是斐波那契数列问题 假设f(n)是n个台阶跳的次数:(假设已经调到第n个台阶,最后一次是由哪个台阶跳上来的) f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) == f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) == f(n) = 2*f(n-1) 所以,可以得出递推式: 1 public static int jumpFloor(int n) { 2 if (n <= 0) 3 return 0; 4

错排递推式推导

今天听课讲容斥,提到错排,突然发现错排公式什么的好像已经忘了233 努力地回忆了一下,算出前几项,终于还原出了那个递推式↓ f(n)=(n-1)*(f(n-1)+f(n-2)) 根据人赢的教导,只要思(yi)考(yin)下错排的构造就能记住了 然后就认(meng)认(you)真(yi)真(yang)地思(yi)考(yin)了下 用自己的理解把这玩意儿整理了一下↓ 先加一点平时我们说的错排通常是指1~n,f(i)≠i, 其实脑补一下,它也可以看成A,B两个集合,|A|=|B|,对于每一个Ai,都对

hdu 1757 A Simple Math Problem (构造矩阵解决递推式问题)

题意:有一个递推式f(x) 当 x < 10    f(x) = x.当 x >= 10  f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + -- + a9 * f(x-10) 同时ai(0<=i<=9) 不是 0 就是 1: 现在给你 ai 的数字,以及k和mod,请你算出 f(x)%mod 的结果是多少 思路:线性递推关系是组合计数中常用的一种递推关系,如果直接利用递推式,需要很长的时间才能计算得出,时间无法承受,但是现在我们已知

[题解][SHOI2013]超级跳马 动态规划/递推式/矩阵快速幂优化

这道题... 让我见识了纪中的强大 这道题是来纪中第二天(7.2)做的,这么晚写题解是因为 我去学矩阵乘法啦啦啦啦啦对矩阵乘法一窍不通的童鞋戳链接啦 层层递推会TLE,正解矩阵快速幂 首先题意就是给你一个 n 行m 列 的格子图 一只马从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行. 题意很简单暴力dp的思路也很简单但是数据很恶心虽然远古一点,但毕竟是省选题 1 ≤ n ≤ 50,2 ≤ m ≤ 10^9 不过还是给了我们一点提示:n这么小? 总之我们先找出转移式对于每一个点

矩阵乘法(四):分析问题,确定递推式,采用矩阵快速幂求解

应用矩阵快速幂运算可以解决递推问题.在实际应用中,有时候题目并没有直接给出递推式,需要认真分析问题,找出递推式,然后再利用矩阵快速幂运算加快问题的求解. [例1]程序阅读理解. 有如下的C语言程序: #include <stdio.h>int main(){     int n,m,f,i;     while(scanf("%d%d",&n,&m)!=EOF)     {           f=0;           for(i=1;i<=n;i

递推式转化为矩阵形式

EXAMPLE: 递推式: d(n + 2) = p * d(n + 1) + (1 - p) * d(n); 令G(n) = (d(n + 2), d(n + 1))^T; 则 G(n + 1) = M * G(n); 解得 M = p   1 - p 1    0 G(n) = (M ^ n) * G(0); #

hiho 1143 矩阵快速幂 求递推式

题目链接: hihocoder 1143 思路见题目上 快速幂模板: // m^n % k int quickpow(int m,int n,int k) { int b = 1; while (n > 0) { if (n & 1) b = (b*m)%k; n = n >> 1 ; m = (m*m)%k; } return b; } 题解: #include<iostream> #include<cstdio> #include<cstring