动态规划_斐波那契数列

动态规划及斐波那契举例


定义:动态规划(Dynamic Programming DP)是一种多阶段决策优化方法,在数学、计算机科学和经济学中使用。
初衷:使用分治法将大问题分解为若干个小问题进行求解。而其中,许多子问题需要重复求解。当 n 很大时效率很低。那么,我们就想到了,能否将已经求解的子问题的解保存下来,再需要使用子问题解的时候,直接给出解,避免进行重复求解,以达到优化算法,降低算法求解时间的目的。

动态规划方法的实质是分治思想和解决冗余:

  • 分治思想:将原解问题分解为更小 、 更易求解的子问题,然后对子问题进行求解,并最终产生原问题的解。
  • 解决冗余:求解过程中所有子问题只求解一次 并以表的方式保存,对于相同子问题,并不重复求解而通过查表的方式获得。

下面举一个斐波那契数列的例子,分别使用递归非动态规划、递推、递归动态规划三种方式求解。

n12345678……
F(n)1123581321……
#include <iostream>

using namespace std;

// 非动态规划的斐波那契函数
int Fib(int n) {
	// 第一项和第二项都是1,直接进行返回
	if (n == 1 || n == 2) {
		return 1;
	}
	// 后一项等于前两项之和
	return Fib(n - 1) + Fib(n - 2);
}

/**
 * 使用动态规划的斐波那契函数
 * @param n 数组a中的第几项
 * @param a 记录数组,将已经求解的记录下来
 */
int Fib_DP(int n, int *a) {
	// a[n]不等于-1时,证明该项已经求解过了,不需要重复进行求解,直接把值返回就行
	if (a[n] != -1) {
		return a[n];
	}
	else {
		// a[n]为-1时,证明没有求解过,需要递归进行求解
		// 求解之后不仅要返回,还要进行记录,避免重复求解
		a[n] = Fib_DP(n - 1, a) + Fib_DP(n - 2, a);
		return a[n];
	}
}

int main() {
	int n = 0;

	cout << "请输入斐波那契数列的项数 : ";
	cin >> n;
	cout << "--------------------------------------------" << endl;
	cout << "递归非动态规划 : " << Fib(n) << endl;

	int* a = new int[n];
	// 前两项的值可以直接得到
	a[0] = a[1] = 1;
	// 根据前两项的值,使用关系式,递推的得到结果
	for (int i = 2; i < n; i++) {
		a[i] = a[i - 1] + a[i - 2];
	}
	cout << "--------------------------------------------" << endl;
	cout << "使用递推 : " << a[n - 1] << endl;


	int* dp = new int[n + 1];
	// 将初始值设置为-1,和赋值过的进行区分
	for (int i = 0; i < n + 1; i++) {
		dp[i] = -1;
	}
	//前两项设置为1
	dp[1] = dp[2] = 1;
	cout << "--------------------------------------------" << endl;
	cout << "使用递归动态规划 : " << Fib_DP(n,dp) << endl;
	
	delete []a;
	delete []dp;
	return 0;
}

运行结果:运行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

中小庸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值