算法学习——动态规划入门

本文介绍了动态规划的概念,通过斐波那契数列作为起点,探讨了如何解决最佳选择问题,包括选择多个任务获取最高报酬和选择不相邻数求最大和,并解决是否存在特定数和的子集问题。文章提供了JavaScript实现的代码示例,展示了动态规划从递归到自顶向下优化的过程。
摘要由CSDN通过智能技术生成

很久没有接触动态规划了,通过b站正月点灯笼的视频重新学习了一遍:学习视频地址。总结了一下文字版方便复习:(因为最近都在学习JS,代码部分会用JS写一遍,算法核心不变)

Fibonacci Sequence斐波那契数列

用斐波那契数列理解动态规划问题:我们知道斐波那契数列有个递归公式fib(n) = fib(n-1) + fib(n-2)。所以通过递归我们可以轻松的实现求fib(n)
在这里插入图片描述
JavaScript实现:

function fib(n) {
   
	if (n == 1 || n == 2) return 1;
	return fib(n-1) + fib(n-2);
}

但是这样实现会有一个问题,就是会出现重叠子问题,导致我们递归算法的时间复杂度比较高O(2^n)

什么是重叠子问题(overlap sub-problem)呢?我们看下面的树状分析图,当我们要计算fib(7)的时候,fib(5)fib(4)…等等都要计算两次,这就是重叠子问题。如果我们能将fib(i)的值存储起来,避免重复计算,时间复杂度就能大大减少。

在这里插入图片描述
也就是说我们放弃递归,而是采取从前往后计算,如下图,时间复杂度就会变为O(n)
在这里插入图片描述
JavaScript代码实现:

function fib(n) {
   
	var arr = [1,1];
	if (n < 3) return arr[n - 1];
	for (let i = 2; i < n; i++) {
   
		arr[i] = arr[i-1] + arr[i-2];
	} 
	return arr[n-1]
}

这第二种解法就是动态规划的雏形了。理解了斐波那契数列问题后,来看下面这个题目:

1.最佳选择问题One

Q:时间坐标系里有从上到下八个任务,它们的横坐标表示必须在[i,j]时间段内完成,红色的数字表示完成该项目后能获得的报酬。问选择任意多个任务后能获得的最多报酬是多少?(同一时间只能做单一个项目)
在这里插入图片描述

通常动态规划的问题就是选和不选的问题,我们先写出递归公式:

  • OPT(i):前i个任务可能获得的最高报酬
  • v(i):第i个任务的报酬
  • prev(i):如果选了第i个,前面最近能选的任务编号
    在这里插入图片描述

JavaScript代码实现:

//递归算法:
var tasks = [5, 1, 8, 4, 6, 3, 2, 4];
var prev = [0, 0, 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值