`
yeshaoting
  • 浏览: 684718 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

动态规划与分治法 — 求解Fibonacci数列

阅读更多

 

Fibonacci数列
无穷数列11235813213455称为Fibonacci数列。它可以递归地定义为:

1. 分治法求Fibonacci数列   
分治法将具有最优子结构性质的原问题分解成若干个子问题, 子问题相互独立.

分治法通常采用递归操作实现.

 

/*
@author: jarg
@TODO: 分治法求Fibonacci数列
*/

import java.io.InputStreamReader;

public class Fibonacci
{
	public static void main(String[] args)
	{
		InputStreamReader ir = new InputStreamReader(System.in);
		try
		{
			System.out.print("输入参数n: ");
			int n = Integer.parseInt("" + (char)ir.read());
			System.out.println("Fibonacci(" + n +")=" + fibonacci(n));
		}
		catch(Exception e)
		{
			System.out.println("invalid input.");
		}
	}

	/* 求Fibonacci数列 */
	public static int fibonacci(int n)
	{
		if(n<2)
		{
			return 1;
		}
		return fibonacci(n-1) + fibonacci(n-2);
	}
}

 

 

2. 动态规划求Fibonacci数列

 动态规划也将具有最优子结构性质的原问题分解成若干个子问题, 且原问题具有重叠子问题性质.

 

/*
@author: jarg
@TODO: 动态规划求Fibonacci数列
*/

import java.io.InputStreamReader;

public class Fibonacci
{
	public static void main(String[] args)
	{
		InputStreamReader ir = new InputStreamReader(System.in);
		try
		{
			System.out.print("输入参数n: ");
			int n = Integer.parseInt("" + (char)ir.read());
			System.out.println("Fibonacci(" + n +")=" + fibonacci(n));
		}
		catch(Exception e)
		{
			System.out.println("invalid input.");
		}
		
	}

	/* 求Fibonacci数列 */
	public static int fibonacci(int n)
	{
		int result = 1,f1 = 1,f2 = 1;

		/* 边界条件: n<2 */
		if(n<2)
		{
			return 1;
		}
		for(int i=2;i<=n;i++)
		{
			result = f1 + f2;
			f1 = f2;
			f2 = result;
		}
		return result;
	}
}

 

 

当递归分解得到的子问题不互相独立时,若用分治法求解,则有些子问题会被重复计算多次。 例如:

fibonacci(5) = fibonacci(4) + fibonacci(3);

fibonacci(4) = fibonacci(3) + fibonacci(2);

分治法求解时fibonacci(3)被计算至少二次.

而动态规划法通过保存已解决的子问题的解,在需要时再找出已求得的解,可以避免大量重复计算。

  • 大小: 8.6 KB
分享到:
评论
3 楼 jiji879 2011-07-13  
yeshaoting 写道
sd6733531 写道
恕我愚笨。
我感觉第一个是用递归解。
第二个不是用递归解。
其他区别就看不出了。- -!


我也是最近才捡起的算法设计与分析.分析不准确的地方谅解.

确实这二个程序的区别之一是: 第一个用递归解,第二个用非递归解.
不过这只是分治法和动态规划具体实现的区别.

分治法与动态规划实现方法:
① 分治法求解几乎都要用到递归.
② 动态规划既可以用自底向上的迭代法(动态规划求解问题常用的方法),也能用具有记忆功能的递归法自顶向下求解.

分治法与动态规划主要共同点:
都是就是将原问题分而治之,分成若干个子问题.然后将子问题的解合并,形成原问题的解.

分治法与动态规划主要区别:
① 分治法将分解后的子问题看成相互独立的.
② 动态规划将分解后的子问题理解为相互间有联系,有重叠部分.

例如: 求解fibonacci(5)时,得求解fibonacci(4)和fibonacci(3).而求解fibonacci(4)时又得重新求解fibonacci(3).
在分治法中,求解完fibonacci(4)后还得重新求解fibonacci(3),也就是说求解了二次子问题fibonacci(3).
动态规划为了避免子问题fibonacci(3)的重复求解,将其解保存下来.

分治法与动态规划适用条件:
① 原问题具有最优子结构性质的前提下,分解出的子问题都绝对相互独立.
② 原问题具有最优子结构性质的前提下,分解出的子问题并不相互独立,求解一个子问题可能要用到已经求解过的子问题的解.子问题间具有重叠性,即要求原问题具有重叠子结构性质.

分治法与动态规划复杂度分析:
① 分治法因为对子问题进行了多次求解,所以效率比动态规划低一点.(时间复杂度相对高)
② 动态规划求解需要将子问题的解保存下来,所以会比分治法多用一些空间.(空间复杂度相对高)
其实,算法世界里,要么用时间换空间,要么用空间换时间.

int fibonacci(Integer n){
		if(list.get(n-1)!=0){
			return list.get(n-1);
		}
		list.add(n-1,fibonacci(n-1)+fibonacci(n-2));
		return list.get(n-1);
	}

貌似这才是动态规划的解。
2 楼 yeshaoting 2011-01-07  
sd6733531 写道
恕我愚笨。
我感觉第一个是用递归解。
第二个不是用递归解。
其他区别就看不出了。- -!


我也是最近才捡起的算法设计与分析.分析不准确的地方谅解.

确实这二个程序的区别之一是: 第一个用递归解,第二个用非递归解.
不过这只是分治法和动态规划具体实现的区别.

分治法与动态规划实现方法:
① 分治法求解几乎都要用到递归.
② 动态规划既可以用自底向上的迭代法(动态规划求解问题常用的方法),也能用具有记忆功能的递归法自顶向下求解.

分治法与动态规划主要共同点:
都是就是将原问题分而治之,分成若干个子问题.然后将子问题的解合并,形成原问题的解.

分治法与动态规划主要区别:
① 分治法将分解后的子问题看成相互独立的.
② 动态规划将分解后的子问题理解为相互间有联系,有重叠部分.

例如: 求解fibonacci(5)时,得求解fibonacci(4)和fibonacci(3).而求解fibonacci(4)时又得重新求解fibonacci(3).
在分治法中,求解完fibonacci(4)后还得重新求解fibonacci(3),也就是说求解了二次子问题fibonacci(3).
动态规划为了避免子问题fibonacci(3)的重复求解,将其解保存下来.

分治法与动态规划适用条件:
① 原问题具有最优子结构性质的前提下,分解出的子问题都绝对相互独立.
② 原问题具有最优子结构性质的前提下,分解出的子问题并不相互独立,求解一个子问题可能要用到已经求解过的子问题的解.子问题间具有重叠性,即要求原问题具有重叠子结构性质.

分治法与动态规划复杂度分析:
① 分治法因为对子问题进行了多次求解,所以效率比动态规划低一点.(时间复杂度相对高)
② 动态规划求解需要将子问题的解保存下来,所以会比分治法多用一些空间.(空间复杂度相对高)
其实,算法世界里,要么用时间换空间,要么用空间换时间.
1 楼 sd6733531 2011-01-07  
恕我愚笨。
我感觉第一个是用递归解。
第二个不是用递归解。
其他区别就看不出了。- -!

相关推荐

    算法设计实验报告之多种方法求解斐波那契数列

    3. **公式法**:斐波那契数列可以通过数学公式F(n) = [φ^n / sqrt(5)] + [(1 - φ)^n / sqrt(5)]的整数部分来求解,其中φ是黄金比例约等于1.618。虽然这种方法在理论上更高效,但由于涉及到浮点数运算,可能会影响...

    【C++】斐波那契数列应用的一个实例

    【C++】斐波那契数列应用的一个实例。这是关于斐波那契数列的一个例子,用C++语言实现

    动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。

    例如,斐波那契数列的动态规划解法就是通过递归定义每一项与前两项的关系。 3. **自底向上的计算**:从基础情形开始,逐步计算出所有子问题的解,存储在表格中,避免了重复计算。这个过程被称为记忆化。 4. **构造...

    算法代码(回溯法,动态规划,分治法,贪心)

    这个压缩包文件包含了四种基本的算法实现:回溯法、动态规划、分治法和贪心算法。这些都是计算机科学中极其重要的概念,对于理解和解决复杂问题至关重要。 1. **回溯法**:回溯法是一种试探性的解题策略,它尝试...

    数据结构与算法-五大常用算法总结(分治法,回溯法,分治限界法,贪心算法,动态规划法),算法数据结构

    比如,斐波那契数列、背包问题等都可以用动态规划求解。与分治法和回溯法相比,动态规划更注重最优解的方向,并且不回溯,因此效率更高。 这五大算法在解决问题时各有特点,适用场景也有所不同。了解和掌握这些算法...

    算法分析 递归与分治策略 动态规划 贪心算法 分支限界法 随机化算法等算法

    例如,著名的斐波那契数列和背包问题都可以用动态规划求解。它通过存储和重用子问题的解,避免了重复计算,提高了效率。 3. **贪心算法**: 贪心算法在每一步选择中都采取在当前状态下最好或最优的选择,以期望...

    算法分析的PPT(贪心,动态规划,分治,递归)

    例如,经典的斐波那契数列和背包问题,都可以通过动态规划实现空间和时间效率的优化。动态规划的优势在于能避免重复计算,存储和利用子问题的解,以达到全局最优。 3. **分治法**: 分治法是将一个复杂问题分解为...

    算法分析课件(堆和不相交数据结构,归纳法,分治法,动态规划,贪心算法,回溯法)

    例如,斐波那契数列可以通过归纳法进行定义和求解。 分治法是一种将大问题分解为小问题并分别解决的策略。它通常包括三个步骤:分解、解决和合并。经典的分治算法有快速排序、归并排序和大数乘法等。分治法能有效地...

    c#精典五大算法 分治,动态规划,回溯法

    C#中的斐波那契数列、背包问题等经典问题都可以用动态规划解决。动态规划的关键在于状态转移方程和最优子结构,通过构造一个表格来保存中间结果,逐步求得最终解。文件Arith02.cs和Arith04.cs可能涉及了动态规划的...

    最近对问题/c++/蛮力法,分治法+报告

    以求解最大子序列和问题为例,我们可以使用分治法将大数组分为两部分,分别求解子序列和,然后比较两个子序列和的最大值与原数组中的负数,取其中的最大值作为最终结果。 在比较蛮力法和分治法时,我们可以关注计算...

    分治递归动态规划贪心常用算法实例

    分治法是一种处理大问题的策略,它将大问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题,然后递归地解决这些子问题,最后将子问题的解合并得到原问题的解。一个经典的分治例子是快速排序,它通过选取...

    动态规划专项练习

    1. **基本概念**:解释动态规划的定义,以及它与分治法、贪心法的区别。 2. **基本步骤**:列出解决动态规划问题的通用步骤,如定义状态、确定状态转移方程、初始化边界条件、构建解决方案。 3. **经典模型**:介绍...

    digui.rar_分治法_经典算法_递归 算法

    分治法的核心思想是将问题的规模减小,直到问题变得足够简单,可以直接求解。这种算法在排序(如快速排序、归并排序)、搜索(如二分查找)等领域有广泛应用。 递归(Recursion)是另一种与分治法紧密相关的概念,...

    算法5_分治法1

    对于有重叠子问题的情况,如斐波那契数列,更适合使用动态规划来优化。分治法和递归是算法设计中的重要概念,它们在解决复杂计算问题时发挥着重要作用。理解并掌握这些方法,对提升算法设计能力非常有益。

    suanfafenxi.rar_动态规划法

    动态规划法是一种强大的算法设计策略,它通过将复杂问题分解为相互重叠的子问题来求解。在标题“suanfafenxi.rar_动态规划法”中,我们可以推测这是一个关于动态规划法的资料包,可能包含了一系列相关算法的详细分析...

    动态规划动态规划动态规划

    ### 动态规划的核心概念与应用 #### 一、动态规划概述 动态规划是一种用于解决最优化问题的有效算法思想。这类问题的特点在于存在多种可能的解决方案,并且每个解都有一个对应的值。我们的目标通常是找到一个最优...

    算法导论学习笔记三之分治法与递归式解法

    **算法导论学习笔记三之分治法与递归式解法** 在计算机科学中,分治法(Divide and Conquer)和递归式(Recursive Formulation)是解决复杂问题的强大工具。这两种方法通常相互结合,使得我们能够对大型问题进行...

    动态规划算法简介 很详细

    这也是动态规划与分治法的主要区别,后者通常处理独立的子问题。 设计动态规划算法通常涉及以下四个步骤: 1. **确定最优解的性质**:理解问题的最优解如何由子问题的最优解组合而成。 2. **定义最优值**:建立...

Global site tag (gtag.js) - Google Analytics