入门动态规划(一)——斐波那契数列问题

177 阅读1分钟

这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

前言

动态规划(第2讲)_哔哩哔哩_bilibili

不说了,就看上面的那个。

斐波那契数列问题的引入

斐波那契数列:

1 1 2 3 5 8 ...

我们可以用递归的写法实现斐波那契数列,这很容易。

主要思想就是这个公式 :f(n)=f(n-1)+f(n-2)

就不放出代码了。

但问题是我们都知道递归的效率是很低的,如果数字稍大的话,使用递归处理数据是不合适的。

这里我们可以观察斐波那契数列的特点。我们就假设求f(5),即斐波那契数列的第五位。

根据公式,f(5)=f(4)+f(3),按照递归的做法,我们会再求f(4),f(4)=f(3)+f(2),f(3)=f(2)+f(1)。

当我们处理完f(4)后,我们再对f(3)处理。

image.png

这里我们发现当我们求右边的f(3)时,我们重复进行了对f(3)的求解。

image.png

这里就有了重复子问题的概念,而这也是动态规划最显要的特征。

package day_04;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.math.BigDecimal;

public class 斐波那契数列 {

	public static void main(String[] args) throws FileNotFoundException {
		int n=100000;
		
		PrintWriter out =new PrintWriter(new FileOutputStream("2.txt"));
		
		
		BigDecimal[] a=new BigDecimal[n+1];
		a[1]=BigDecimal.ONE;
		a[2]=BigDecimal.ONE;
		BigDecimal num=fun(n,a);
		
		out.print(num.toString());
		out.close();
		
		//System.out.println(num);
	
	}
	
	static BigDecimal fun(int n,BigDecimal[] a) {
		
		for(int i=3;i<=n;i++) {
			a[i]=a[i-1].add(a[i-2]);
		}
		
		return a[n];
		
	}

}

这里的数组a就用于存储重复子问题的解答。

这里顺便复习了一下之前的求超大数结果的解决方法。

PrintWriter out =new PrintWriter(new FileOutputStream("2.txt"));

out.print(num.toString());

out.close();

结果可以到2万多位

image.png