递归算法
- 格式:doc
- 大小:112.50 KB
- 文档页数:9
递归算法及经典例题详解
1.什么是递归
递归简单来说就是在运行过程中不断调用自己,直到碰到终止条件,返回结果的过程。
递归可以看作两个过程,分别是递和归。
递就是原问题把要计算的结果传给子问题;归则是子问题求出结果后,把结果层层返回原问题的过程。
下面设一个需要经过三次递归的问题,为大家详细看一下递归的过程:当然,现实中我们遇到递归问题是不会按照图中一样一步一步想下来,主要还是要掌握递归的思想,找到每个问题中的规律。
2.什么时候使用递归
递归算法无外乎就是以下三点:1.大问题可以拆分为若干小问题2.原问题与子问题除数据规模不同,求解思路完全相同3.存在递归终止条件
而在实际面对递归问题时,我们还需要考虑第四点:
当不满足终止条件时,要如何缩小函数值并让其进入
下一层循环中
3.递归的实际运用(阶层计算)
了解了大概的思路,现在就要开始实战了。
下面我们来看一道经典例题:
求N的阶层。
首先按照思路分析是否可以使用递归算法:
1.N!可以拆分为(N-1)!*N
2.(N-1)!与N!只有数字规模不同,求解思路相同
3.当N=1时,结果为1,递归终止
满足条件,可以递归:
publicstaticintFactorial(int num){if(num==1){return num;}return num*Factorial(num-1);}
而最后的return,便是第四步,缩小参数num的值,让递归进入下一层。
一般来说,第四步往往是最难的,需要弄清该如何缩
小范围,如何操作返回的数值,这一步只能通过不断
地练习提高了(当然如果你知道问题的数学规律也是
可以试出来的)。
数据结构递归算法例子数据结构中的递归算法是指一个函数在其定义中调用自身的过程。
递归算法在解决一些问题时非常有效,因为它可以将复杂的问题分解为更小的子问题来解决。
在本文中,我将列举一些常见的数据结构递归算法的例子,来帮助读者更好地理解递归的概念和应用。
1. 阶乘算法:计算一个正整数的阶乘。
阶乘的定义是n! = n * (n-1) * (n-2) * ... * 1。
使用递归算法可以简洁地实现阶乘的计算,代码如下:```pythondef factorial(n):if n == 0:return 1else:return n * factorial(n-1)```2. 斐波那契数列:斐波那契数列是一个数列,其中每个数字是前两个数字之和。
使用递归算法可以很容易地计算斐波那契数列的第n 个数字,代码如下:```pythondef fibonacci(n):if n <= 1:return nelse:return fibonacci(n-1) + fibonacci(n-2)```3. 二叉树遍历:二叉树是一种常见的数据结构,它包含一个根节点和每个节点最多有两个子节点。
使用递归算法可以实现二叉树的前序、中序和后序遍历。
下面是一个中序遍历的例子:```pythonclass TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef inorderTraversal(root):if root:inorderTraversal(root.left)print(root.val)inorderTraversal(root.right)```4. 链表反转:链表是一种常见的数据结构,通过指针将一组节点连接在一起。
使用递归算法可以反转一个链表,即将链表的指针方向改变。
递归算法详解完整版递归算法是一种重要的算法思想,在问题解决中起到了很大的作用。
它通过将一个大问题划分为相同或类似的小问题,并将小问题的解合并起来从而得到大问题的解。
下面我们将详细介绍递归算法的定义、基本原理以及其应用。
首先,我们来定义递归算法。
递归算法是一种通过调用自身解决问题的算法。
它通常包括两个部分:基础案例和递归步骤。
基础案例是指问题可以被直接解决的边界情况,而递归步骤是指将大问题划分为较小问题并通过递归调用自身解决。
递归算法的基本原理是"自顶向下"的思维方式。
即从大问题出发,不断将问题划分为较小的子问题,并解决子问题,直到达到基础案例。
然后将子问题的解合并起来,得到原始问题的解。
递归算法的最大特点是简洁而优雅。
通过将复杂问题分解为简单问题的解决方式,可以大大减少代码的复杂程度,提高程序的效率和可读性。
但是递归算法也有一些缺点,包括递归深度的限制和复杂度的不确定性。
过深的递归调用可能导致栈溢出,而不合理的递归步骤可能导致复杂度过高。
递归算法有许多应用场景,我们来介绍其中一些典型的应用。
1.阶乘问题:计算一个数的阶乘。
递归算法可以通过将问题划分为更小的子问题来解决。
例如,n的阶乘可以定义为n乘以(n-1)的阶乘。
当n 等于1时,我们可以直接返回1作为基础案例。
代码如下:```int factorial(int n)if (n == 1)return 1;}return n * factorial(n - 1);```2.斐波那契数列问题:求斐波那契数列中第n个数的值。
斐波那契数列的定义是前两个数为1,然后从第三个数开始,每个数都是前两个数的和。
递归算法可以通过将问题划分为两个子问题来解决。
当n等于1或2时,直接返回1作为基础案例。
代码如下:```int fibonacci(int n)if (n == 1 , n == 2)return 1;}return fibonacci(n - 1) + fibonacci(n - 2);```3.二叉树问题:对于给定的二叉树,递归算法可以通过递归调用左子树和右子树的解来解决。
6种基本算法递归递归是一种重要的算法思想,它在计算机科学中得到广泛应用。
本文将介绍六种基本的递归算法,并对其原理和应用进行讲解。
一、递归的基本概念递归是指一个函数在其定义中调用自身的过程。
递归算法通过将一个大问题划分为一个或多个相同或相似的子问题,然后通过解决子问题来解决原始问题。
递归算法具有简洁、优雅以及可读性强的特点,但同时也需要注意递归的停止条件,以避免无限递归的发生。
二、阶乘算法阶乘算法是递归算法中最经典的例子之一。
它的定义如下:```n! = n * (n-1) * (n-2) * ... * 1```其中,n为一个非负整数。
阶乘算法可以通过递归的方式实现,即:```fact(n) = n * fact(n-1)```其中,停止条件为`n=0`时,返回1。
三、斐波那契数列算法斐波那契数列是一个无限序列,其定义如下:```F(0) = 0F(1) = 1F(n) = F(n-1) + F(n-2) (n>1)```斐波那契数列算法可以通过递归的方式实现,即:```fib(n) = fib(n-1) + fib(n-2)```其中,停止条件为`n=0`或`n=1`时,返回相应的值。
四、二分查找算法二分查找算法是一种高效的查找算法,它的基本原理是将已排序的数组分成两部分,然后判断目标值在哪一部分,并继续在该部分中进行查找,直到找到目标值或者查找范围为空。
二分查找算法可以通过递归的方式实现,即:```binarySearch(arr, target, start, end) = binarySearch(arr, target, start, mid-1) (target < arr[mid])= binarySearch(arr, target, mid+1, end) (target > arr[mid])= mid (target = arr[mid])```其中,`arr`为已排序的数组,`target`为目标值,`start`和`end`为查找范围的起始和结束位置。
常见递归算法
常见的递归算法包括以下几种:
1. 斐波那契数列:斐波那契数列是一个经典的递归问题,每个数都是前两个数的和。
通过递归可以很容易地计算出斐波那契数列的每一项。
2. 树的遍历:在树的遍历中,递归是一种常见的实现方式。
例如,前序遍历、中序遍历和后序遍历都可以通过递归算法来实现。
3. 汉诺塔问题:汉诺塔问题是一个经典的递归问题,需要将一系列圆盘从一个柱子移动到另一个柱子,且在移动过程中不能将较大的圆盘放在较小的圆盘上面。
递归算法可以有效地解决这个问题。
4. 快速排序算法:快速排序是一种常用的排序算法,它采用了分治法的思想,通过递归将数组分成两部分并对其进行排序。
5. 归并排序算法:归并排序也是一种基于分治思想的排序算法,通过递归将数组分成子数组,然后合并它们以得到排序后的数组。
6. 二分查找算法:二分查找是一种在有序数组中查找特定元素的高效算法。
通过将数组一分为二并递归地在子数组中查找,可以快速缩小查找范围。
7. Tower of Hanoi(汉诺塔)问题:这是一个经典的数学谜题,需要将一系列圆盘从一个柱子移动到另一个柱子,遵循特定的规则。
递归算法可以用来解决这个问题。
这些只是一些常见的递归算法示例,递归在很多其他问题和算法中也有广泛应用。
递归的优点是代码简洁易懂,但需要注意防止递归深度过大导致栈溢出等问题。
在实际应用中,需要根据具体情况选择合适的算法和数据结构来解决问题。
递归算法递推公式求解递归算法是一种自我调用的算法,它通过不断将问题分解为更小的子问题来求解问题。
递归算法的核心是递推公式,也称为递归式,它描述了如何将问题分解为子问题,并如何从子问题的解中得到原问题的解。
递推公式通常具有以下形式:T(n) = aT(n/b) + f(n)其中,T(n) 表示问题规模为n 时的时间复杂度,a 表示每次递归调用的次数,b 表示每次递归调用后问题规模缩小的比例,f(n) 表示除了递归调用外的其他操作的时间复杂度。
为了求解递推公式,我们可以使用以下方法:1.迭代法:通过迭代递推公式的方式逐步计算出T(n) 的值。
这种方法比较直观,但对于较大的n 值,迭代次数可能非常多,计算量也会非常大。
2.替换法:通过猜测T(n) 的形式,并将其代入递推公式中进行验证。
如果猜测正确,则可以得到T(n) 的解。
这种方法需要对问题有一定的了解和猜测能力。
3.大师定理:大师定理是一种求解递推公式的通用方法。
它可以根据递推公式的形式,直接给出T(n) 的时间复杂度。
大师定理有多种形式,其中最常用的是以下三种:a. 如果f(n) = O(n^c),其中c < log_b(a),则T(n) = O(n^log_b(a))。
b. 如果f(n) = O(n^c),其中c = log_b(a),则T(n) = O(n^c * log_n)。
c. 如果f(n) = O(n^c),其中c > log_b(a),且对于所有足够大的n,有af(n/b) <= f(n),则T(n) = O(f(n))。
需要注意的是,大师定理只是一种求解递推公式的工具,它并不能解决所有类型的递推公式。
在实际应用中,我们需要根据具体问题选择合适的求解方法。
著名递归算法
以下是一些著名的递归算法:
1. 快速排序算法:是一种常用的排序算法,它通过递归地分割数组来
排序。
2. 斐波那契数列:一种递归的数列,通过一个简单的递归函数生成前
两个斐波那契数,然后将结果乘以递归调用的次数得到后续的斐波那
契数。
3. 汉诺塔问题:这是一个经典的递归问题,要求将一堆金字塔从一个
大圆盘移动到另一个小圆盘,每次只能移动一个大圆盘或小圆盘上的
一个盘子。
4. 递归函数:在编程中,递归函数是一种通过自我调用自身来实现特
定功能的函数。
例如,Python中的map()、filter()和reduce()等高
阶函数都是递归函数的例子。
5. 分治算法:是一种将一个大问题分解为若干个小问题来解决的方法,这些小问题通常可以通过递归方式解决。
6. 动态规划算法:是一种优化算法,通过将大问题分解为一系列小问
题并存储中间结果来避免重复计算。
动态规划算法通常需要使用递归
来实现。
以上是一些著名的递归算法,它们在计算机科学和数学领域中得到了
广泛的应用。
常见算法及其运算实例分析算法是计算机科学中最重要的一部分。
算法既是计算机科学的基础,又是计算机编程的核心。
了解算法,可以让我们更深入地理解计算机的运行原理,以及如何利用计算机处理各种问题。
本文将为大家介绍几个常见的算法及其运算实例分析。
一、递归算法递归算法是一种函数调用自身的算法。
递归算法具有简单、直观、可理解等优点。
但同时也存在着栈溢出、时间复杂度高等问题。
递归算法通常包含有一些关键参数,如递归的次数和递归深度等,这些参数的变化对于程序的运行和结果都有着重要的影响。
实例:斐波那契数列我们可以通过递归算法来实现斐波那契数列。
斐波那契数列的定义如下:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n>=2)。
通过递归算法,可以很容易地实现斐波那契数列。
我们只需要以递归方式调用F函数即可,代码如下:```def F(n):if n==0:return 0elif n==1:return 1else:return F(n-1)+F(n-2)```二、分治算法分治算法是将问题分解成若干个子问题,然后递归地分别解决每个子问题,最终合并成一个整体的算法。
分治算法通常解决的问题都具备“可分解性”和“合并性”的特征。
实例:二分查找二分查找可以用分治算法来实现。
二分查找的思想是将数组分成两个区间,分别判断目标值是否在每个区间中。
如果目标值存在于某个区间中,则继续在该区间中进行查找;否则在另一个区间中进行查找。
通过分治算法,我们可以将二分查找优化成O(log n)的时间复杂度。
代码如下:```def binary_search(arr, left, right, target):if left > right:return -1mid = (left + right) // 2if arr[mid] == target:return midelif arr[mid] < target:return binary_search(arr, mid+1, right, target)else:return binary_search(arr, left, mid-1, target)```三、贪心算法贪心算法可以理解为通过每步选择中的局部最优解,从而达到全局最优的解决方案。
C语言高级特性递归与回溯算法C语言高级特性:递归与回溯算法递归和回溯算法是C语言中一种非常重要的高级特性,它们在解决一些复杂问题和优化代码时发挥着关键的作用。
本文将会介绍递归和回溯算法的原理和应用,并通过具体的示例来说明它们的使用方法。
一、递归算法递归是指一个函数在执行过程中调用自身的过程。
递归算法通常包括两个部分:递归出口和递归调用。
递归出口是指当满足某个条件时结束递归的条件,而递归调用则是指在函数内部调用自身来解决规模更小的问题。
递归算法在解决一些具有重复性结构的问题时非常高效。
例如,计算一个数的阶乘,可以使用递归算法来实现:```c#include <stdio.h>int factorial(int n) {if (n == 0 || n == 1) { //递归出口return 1;} else {return n * factorial(n - 1); //递归调用}}int main() {int n = 5;printf("The factorial of %d is %d\n", n, factorial(n));return 0;}```上述代码定义了一个计算阶乘的递归函数factorial。
在函数内部,通过递归调用来计算规模更小的问题,直到n等于0或1时返回结果。
二、回溯算法回溯算法是一种通过尝试所有可能的解来找到问题解决方法的搜索算法。
在遇到有多个解可选的情况下,回溯算法会尝试每一种可能,并通过剪枝策略来避免不必要的计算。
回溯算法通常涉及到构建决策树和遍历树上的节点。
以八皇后问题为例,考虑如何在8x8的棋盘上放置8个皇后,使得每个皇后都不会互相攻击。
下面是用回溯算法解决八皇后问题的示例代码:```c#include <stdio.h>#define N 8int board[N][N];int isSafe(int row, int col) {int i, j;// 检查当前位置的列是否安全for (i = 0; i < row; i++) {if (board[i][col] == 1) {return 0;}}// 检查当前位置的左上方是否安全for (i = row, j = col; i >= 0 && j >= 0; i--, j--) { if (board[i][j] == 1) {return 0;}}// 检查当前位置的右上方是否安全for (i = row, j = col; i >= 0 && j < N; i--, j++) { if (board[i][j] == 1) {return 0;}}return 1;}int solve(int row) {int col;if (row >= N) { // 所有行都已经安全放置皇后,找到解 return 1;}for (col = 0; col < N; col++) {if (isSafe(row, col)) {board[row][col] = 1; // 放置皇后if (solve(row + 1)) { // 递归调用return 1;}board[row][col] = 0; // 回溯,撤销放置皇后}}return 0;void printBoard() {int i, j;for (i = 0; i < N; i++) {for (j = 0; j < N; j++) {printf("%d ", board[i][j]); }printf("\n");}}int main() {if (solve(0)) {printf("Solution:\n");printBoard();} else {printf("No solution found.\n"); }return 0;}上述代码使用回溯算法来解决八皇后问题。
递归算法是把问题转化为规模缩小了的同类问题的子问题。
然后递归调用函数(或过程)来表示问题的解。
一个过程(或函数)直接或间接调用自己本身,这种过程(或函数)叫递归过程(或函数)。
算法特点:
递归算法是直接或间接调用自身的算法。
在计算机程序设计中,递归算法对于解决一大类问题非常有效,它经常使算法的描述简洁明了且易于理解。
解决问题的递归算法特点:
(1)递归是在过程或函数中调用自身。
(2)使用递归策略时,必须有明确的递归结束条件,称为递归退出。
(3)递归算法求解问题通常看起来很简洁,但是递归算法求解问题的效率很低。
因此,通常不建议使用递归算法来设计程序。
(4)在递归调用过程中,系统打开了一个堆栈来存储每个层的返回点和局部变量。
太多的递归很容易导致堆栈溢出。
因此,通常不建议使用递归算法来设计程序。
折叠递归算法要求
递归算法所体现的“重复”一般有三个要求:
一是每次调用在规模上都有所缩小(通常是减半);
二是相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入);
三是在问题的规模极小时必须用直接给出解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条件),无条件递归调用将会成为死循环而不能正常结束。
【算法分析】递归算法的⼏个经典例⼦例⼀:整数划分问题 将正整数n表⽰成⼀系列正整数之和:n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。
正整数n的这种表⽰称为正整数n的划分。
求正整数n的不同划分个数。
例如:正整数6有如下11种不同的划分:6;5+1;4+2,4+1+1;3+3,3+2+1,3+1+1+1;2+2+2,2+2+1+1,2+1+1+1+1;1+1+1+1+1+1在本例中,如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加⼀个⾃变量:将最⼤加数n1不⼤于m的划分个数记作q(n,m)。
下⾯对可能出现的四种情况进⾏分析:① m=1: 当m等于1时,对n的划分只可能1+1+1+……+1这⼀种情况。
②m>n时: 当m⼤于n时,由于划分中不可能出现负数,所以{n1, n2, n2,… , nk}(n = n1+n2+n3+……+nk)只可能出现⼩于等于n的整数。
故有q(n, m)=q(n, n)⑤m=n时: 当m等于n时,包含n⾃⾝的划分和没有n的划分两个部分。
⽽包含n⾃⾝的划分只有⼀种情况,故有有q(n, n)=1+q(n,n-1)④m<n时: n的m划分有包含m和不包含m两个部分。
其中包含m的部分⽤集合可表⽰为{m, {x1, x2, x3, 4,…, xk}}(其中x1+x2+……+xk=n-m)【详解见图1】,这部分的划分数为q(n-m, m);⽽不包含m的划分中,最⼤值不能为m,故划分数就等于q(n, m)。
所以在m<n时整数n的划分数为:q(n, m)=q(n, m-1)+q(n-m, m)。
【图1:ipad坏了,⼀时找不到纸,后⾯再补吧。
】递归求整数划分:1int q(int n, int m){2if(m==1){3return1;4 }5else if(m>n){6return q(n,n);7 }8else if(m==n){9return q(n,n-1)+1;10 }11else if(m<n){12return q(n-m, m)+q(n,m-1);13 }14 }。
递归算法和递推算法的原理-概述说明以及解释1.引言1.1 概述递归算法和递推算法是编程中常用的两种算法思想,它们都是一种问题解决的方法论。
递归算法通过将一个大问题分解为一个或多个相同的小问题来解决,而递推算法则是通过给定初始条件,通过逐步推导出后续结果来解决问题。
递归算法是一种自调用的算法,它将一个问题划分为更小规模的相同子问题,并通过调用自身来解决这些子问题。
每个子问题的解决方案被合并以形成原始问题的解决方案。
递归算法具有简洁的代码结构和易于理解的逻辑。
它在一些问题上能够提供高效的解决方案,例如树的遍历、图的搜索等。
递推算法则是从已知的初始条件开始,通过根据给定的递推公式或规则,逐步计算出后续的结果。
递推算法是一种迭代的过程,每一次迭代都会根据已知条件计算得出下一个结果。
递推算法常应用于数学问题,求解斐波那契数列、阶乘等等。
递归算法和递推算法在解决问题时的思路不同,但也存在一些相似之处。
它们都能够将大问题分解成小问题,并通过解决这些子问题来获得问题的解决方案。
而且递归算法和递推算法都有各自适用的场景和优缺点。
本文将详细介绍递归算法和递推算法的原理、应用场景以及它们的优缺点。
通过比较和分析两者的差异,帮助读者理解和选择合适的算法思想来解决问题。
1.2文章结构文章结构部分的内容可以描述文章的整体框架和各个章节的内容概要。
根据给出的目录,可以编写如下内容:文章结构:本文主要探讨递归算法和递推算法的原理及其应用场景,并对两者进行比较和结论。
文章分为四个部分,下面将对各章节的内容进行概要介绍。
第一部分:引言在引言部分,我们将对递归算法和递推算法进行简要概述,并介绍本文的结构和目的。
进一步,我们将总结递归算法和递推算法在实际问题中的应用和重要性。
第二部分:递归算法的原理在第二部分,我们将详细讨论递归算法的原理。
首先,我们会给出递归的定义和特点,探索递归的本质以及递归算法的基本原理。
其次,我们将展示递归算法在不同的应用场景中的灵活性和效果。
递归算法的应用范文
一、什么是递归算法
递归算法是指利用递归的思想来解决一些问题的算法。
它将一个复杂的问题分解成若干个规模较小,相互独立,与原问题形式相似的子问题,递归地求解各个子问题,然后将子问题的解合并为原问题的解。
二、递归算法的基本特征
1、递归算法主要有两个要素:基本问题的解和递归式。
基本问题的解是算法给出的简单的解决方案,而递归式是递归算法的核心,它描述了将复杂的问题划分成若干个子问题的方法。
2、递归算法要求每次调用它在输入上有着明确的变化。
一般来说,递归算法的每次调用都会将输入变得更趋近于基本问题的解,最终递归调用一定会到达基本问题的解,这时结束递归调用,从而问题得到最终解。
3、递归算法可以节省计算机的存储空间。
由于它使用有限的容量就可以解决大量的问题,因此它可以有效地节省存储空间。
三、递归算法的常见应用
1、排序算法:排序算法是日常编程中经常使用的算法,而这些算法中,有许多都采用了递归的思想,比如快速排序和归并排序。
2、算法:算法一般用于在一个有序的集合中其中一元素,而常用的算法有二分查找和深度优先,它们都采用了递归的思想。
学号09770102《算法设计与分析》实验报告一学生姓名专业、班级09软件一班指导教师唐国峰成绩电子与信息工程系2011 年9 月22 日实验一:递归策略运用练习一、实验目的本次实验是针对递归算法的算法设计及应用练习,旨在加深学生对该算法原理的理解,提高学生运用该算法解决问题的能力。
二、实验步骤与要求1.实验前复习课程所学知识以及阅读和理解指定的课外阅读材料;2.学生独自完成实验指定内容;3.实验结束后,用统一的实验报告模板编写实验报告。
4.提交说明:(1)电子版提交说明:a 需要提交Winrar压缩包,文件名为“《算法设计与分析》实验一_学号_姓名”,如“《算法设计与分析》实验一_07770101_张三”。
b 压缩包内为一个“《算法设计与分析》实验一_学号_姓名”命名的顶层文件夹,其下为两个文件夹,一个文件夹命名为“源程序”,另一个文件夹命名为“实验报告电子版”。
其下分别放置对应实验成果物。
(2)打印版提交说明:a 不可随意更改模板样式。
b 字体:中文为宋体,大小为10号字,英文为Time New Roman,大小为10号字。
c 行间距:单倍行距。
(3)提交截止时间:2011年9月22日16:00。
三、实验项目1.运用递归策略设计算法实现下述题目的求解过程。
题目列表如下:(1)运动会开了N天,一共发出金牌M枚。
第一天发金牌1枚加剩下的七分之一枚,第二天发金牌2枚加剩下的七分之一枚,第3天发金牌3枚加剩下的七分之一枚,以后每天都照此办理。
到了第N天刚好还有金牌N枚,到此金牌全部发完。
编程求N和M。
1.题目分析由题意可以推出来每天发放的数目应该为6的倍数,而且满足f[i-1]=f [i]*7/6+(I-1)的递推关系式!2.算法构造在此论证算法设计中的一些必要的设计依据。
首先要找出递推规律f[i-1]=f [i]*7/6+(i-1);发现每天发放的金牌数必须为6的倍数,由此而知n=n+6;f[n]=n;递推得出得出共有金牌数M:f [1]块。
3.算法实现程序源代码(请写入必要的注释)。
#include <iostream>using namespace std;int main(){int n=0;int i;int f[100];//设定一个数组do{n=n+6;//六的倍数f[n]=n;for(i=n;i>0;i--){if(f[i]%6!=0)//跳出循环的条件break;elsef[i-1]=f[i]*7/6+(i-1);}}while(i>0);cout<<"总数为"<<f[1]<<"块"<<endl;for(i=1;i<n+1;i++){int fa=(f[i]-i)/7;cout<<"第"<<i<<"天发放的金牌为"<<f[i]<<"块"<<endl;}return 0;}4.运行结果5.经验归纳在做递推类算法时,找准递推关系,和边界条件是非常重要的!(2)国王分财产。
某国王临终前给儿子们分财产。
他把财产分为若干份,然后给第一个儿子一份,再加上剩余财产的1/10;给第二个儿子两份,再加上剩余财产的1/10;……;给第i个儿子i份,再加上剩余财产的1/10。
每个儿子都窃窃自喜。
以为得到了父王的偏爱,孰不知国王是“一碗水端平”的。
请用程序回答,老国王共有几个儿子?财产共分成了多少份?1..题目分析因为每个儿子得到的都是一样的,最有一个儿子(第n个儿子)分后就没有了说明最有一个儿子得到的为n份,所以总份数为n*n,递推关系满足f[i-1]=f[i]*10/9+i;2.算法构造在此论证算法设计中的一些必要的设计依据。
首先可以找到f[i-1]=f[i]*10/9+i;的递推关系式发现分给每个儿子的分数必须满足9的倍数,最少为9;由题可知n=n+9;3.算法实现程序源代码(请写入必要的注释)。
#include <iostream>using namespace std;int main(){int i=0;int n=0;int f[100];//储存每个儿子分的份数do{n=n+9;f[n]=0;//最有一个分了就没有了f[n-1]=n;//第n个儿子分的的为n分,所以n-i个儿子剩下的为n份for(int i=n-1;i>0;i--){f[i-1]=f[i]*10/9+i;if(f[0]/n!=n&&i==1)break;}}while(i==1);cout<<"国王共有"<<n<<"个儿子"<<endl;cout<<"一共分成了"<<f[0]<<"份"<<endl;return 0;}4.运行结果5.经验归纳要善于理解题意,挖掘出题目中的隐含条件,是做好此类题目的关键!(3)出售金鱼问题:第一次卖出全部金鱼的一半加二分之一条金鱼;第二次卖出乘余金鱼的三分之一加三分之一条金鱼;第三次卖出剩余金鱼的四分之一加四分之一条金鱼;第四次卖出剩余金鱼的五分之一加五分之一条金鱼;现在还剩下11条金鱼,在出售金鱼时不能把金鱼切开或者有任何破损的。
问这鱼缸里原有多少条金鱼?1题目分析满足递推关系f[n-1]=(f[n]+1/n)*n/(n-1);2算法构造在此论证算法设计中的一些必要的设计依据。
由题意可以退出递推关系式f[n-1]=(f[n]+1/n)*n/(n-1);3算法实现程序源代码(请写入必要的注释)。
#include <iostream>using namespace std;int main(){int f[6]={0,0,0,0,0,0};int n;f[5]=11;for(n=5;n>=2;n--){f[n-1]=(f[n]+1/n)*n/(n-1);}f[1]=2*f[2]+1;cout<<"鱼缸里共有"<<f[1]<<"条金鱼"<<endl;return 0;}4运行结果鱼缸里共有59条鱼5经验归纳(4)某路公共汽车,总共有八站,从一号站发轩时车上已有n位乘客,到了第二站先下一半乘客,再上来了六位乘客;到了第三站也先下一半乘客,再上来了五位乘客,以后每到一站都先下车上已有的一半乘客,再上来了乘客比前一站少一个……,到了终点站车上还有乘客六人,问发车时车上的乘客有多少?1题目分析因为到最后一站还有六个人,而在倒数第一站只上了一个人说明,到倒数第二站到了十个人,以此类推得出了f[i-1]=(f[i]-(8-(i-1)))*2;的关系式;f【i】表示的是到达第i站的人数,所以发车时车上的人数为到第二站时车上的人数。
2算法构造在此论证算法设计中的一些必要的设计依据。
由题意可以退出递推关系式f[i-1]=(f[i]-(8-(i-1)))*2;3算法实现程序源代码(请写入必要的注释)。
#include <iostream>using namespace std;int main(){int i;int n=8;int f[9]={0,0,0,0,0,0,0,0,0};f[8]=6;for (i=n;i>=2;i--){f[i-1]=(f[i]-(8-(i-1)))*2;}cout<<"发车时车上有"<<f[2]<<"个人"<<endl; //发车时车上的人数为到第二站时车上的人数return 0;}4运行结果5经验归纳要学会找到问题的突破口!和转移问题(5)猴子吃桃。
有一群猴子摘来了一批桃子,猴王规定每天只准吃一半加一只(即第二天吃剩下的一半加一只,以此类推),第九天正好吃完,问猴子们摘来了多少桃子?1题目分析因为第九天正好吃完,说明f【9】*1/2=1所以推出来,第九天吃了2个,而不难看出此题满足f[i-1]=(f[i]+1)*2;的递推关系式!2算法构造在此论证算法设计中的一些必要的设计依据。
3算法实现程序源代码(请写入必要的注释)。
#include <iostream>using namespace std;int main(){int f[9]={0,0,0,0,0,0,0,0,0};f[9]=2;//因为第二天正好吃完所以推出来为2!for (int i=9;i>=2;i--){f[i-1]=(f[i]+1)*2;}cout<<"猴子们一共摘了"<<f[1]<<"个桃子"<<endl;return 0;}4运行结果5经验归纳找出题目中的隐含条件很重要(6)小华读书。
第一天读了全书的一半加二页,第二天读了剩下的一半加二页,以后天天如此……,第六天读完了最后的三页,问全书有多少钱页?1题目分析由题意可以推出此题满足f[i-1]=(f[i]+2)*2;的递推关系式!3算法实现程序源代码(请写入必要的注释)。
#include <iostream>using namespace std;int main(){int i;int f[6]={0,0,0,0,0,0};f[5]=3;for(i=5;i>=1;i--){f[i-1]=(f[i]+2)*2;}cout<<"这本书共有"<<f[0]<<"页"<<endl;return 0;}4.运行结果(7)日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。
分完后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7给老三;老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。
结果大家手中的桔子正好一样多。
问六兄弟原来手中各有多少桔子?1题目分析由于最后每个人分得的橘子一样多,我们可以很轻松的算出来,最后每个人手里的橘子为420个,因为每个人在拿到上一个人给的以后又分了一部分给下一个(老大不一样,老大是最后才得到的)而给的份数题目已经给出,所以我们能很轻易的算出自己原来拥有的和得到上一个人给的的橘子的总数;而根据老大和老六的关系我们能推出老的原来手中有240个橘子….2算法构造在此论证算法设计中的一些必要的设计依据。