【算法设计与分析】第二章 递推算法

递推

一个问题的求解需一系列的计算,在已知条件和所求问题之间总存在着某种相互联系的关系,在计算时,如果可以找到前后过程之间的数量关系(即递推式),那么,从问题出发逐步推到已知条件,此种方法叫逆推。

eg:【例1】数字三角形。如下所示为一个数字三角形。请编一个程序计算从顶到底的某处的一条路径,使该路径所经过的数字总和最大。只要求输出总和。
在这里插入图片描述
  1、 一步可沿左斜线向下或右斜线向下走;
  2、 三角形行数小于等于100;
3、 三角形中的数字为0,1,…,99;
测试数据通过键盘逐行输入,如上例数据应以如下所示格式输入:

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

【算法分析】
  此题解法有多种,从递推的思想出发,设想,当从顶层沿某条路径走到第i层向第i+1层前进时,我们的选择一定是沿其下两条可行路径中最大数字的方向前进,为此,我们可以采用倒推的手法,设a[i][j]存放从i,j 出发到达n层的最大值,则a[i][j]=max{a[i][j]+a[i+1][j],a[i][j]+a[i+1][j+1]},a[1][1] 即为所求的数字总和的最大值。

【代码】

#include<bits/stdc++.h>
using namespace std;

int n;
int a[1000][1000];

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
        {
            cin>>a[i][j];
        }
    }
    for(int i=n-1;i>=1;i--)
    {
        for(int j=1;j<=i;j++)
        {
            a[i][j]=max(a[i+1][j],a[i+1][j+1]);
        }
    }
    cout<<a[1][1]<<endl;
    return 0;
}

序列求和的方法

等差数列:
S n = n ( a 1 + a n ) / 2 S_n=n*(a_1+a_n)/2
等比数列:
S n = a 1 ( 1 q n ) / ( 1 q ) ; ( q ! = 1 ) S_n=a_1*(1-q_n)/(1-q);(q!=1)
S n = n a 1 ; ( q = = 1 ) S_n=n*a_1;(q==1)

调和级数:
k = 1 n ( 1 / k ) = l n n + O ( 1 ) \sum_{k=1}^{n} (1/k)=lnn+O(1)

递推方程

设序列 a 0 a_0 , a 1 a_1 ,…, a n a_n ,…简记为 a n {a_n} ,一个把 a n a_n 与某些个 a i a_i 联系起来的等式叫做冠以 a n {a_n} 的递推方程。
求解
给定关于序列 a n {a_n} 的递推方程和若干初值,计算 a n a_n

eg:Fibonacci数列: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …
初值: f 0 = 1 f_0=1 , f 1 = 1 f_1=1
递推方程: f n = f n 1 + f n 2 f_n=f_{n-1}+f_{n-2}

迭代法求解递推方程

迭代法

  • 不断用递推方程的右部替换左部
  • 每次替换,随着 n 的降低在和式中多出一项
  • 直到出现初值停止迭代
  • 将初值代入并对和式求和
  • 可用数学归纳法验证解的正确性

换元迭代

  • 将对 n 的递推式换成对其他变元k的递推式
  • 对 k 直接迭代
  • 将解 (关于 k 的函数) 转换成关于n 的函数

差消法化简高阶递推方程

根据已知,写出递推方程,并且写出递推方程的下一项,,讲两个递推方程做差,然后化简即可。

发布了328 篇原创文章 · 获赞 107 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43460224/article/details/104760161