7.3 算法设计与分析-动态规划法和贪心法

动态规划法

考的最多
动态规划法(Dynamic Programming):在求解问题中,对于每一步决策,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其它局部解,以每一步都是最优解来保证全局是最优解。

本质也是将复杂的问题划分成一个个子问题,与分治法不同的是分治法中的每个子问题都是相同的,而动态规划法中的每个子问题间不是相互独立的,并且不全都相同

此算法会将大量精力放在前期构造表格上面,其会对每一步,列出各种可能的答案,这些答案会存储起来,最终要得出某个结果时,是通过查询这张表来得到的。动态规法不但每一步最优,全局也最优

总结:动态规划一定是具备了以下三个特点:

  • 把原来的问题分解成了几个相似的子问题。(强调“相似子问题”)
  • 所有的子问题都只需要解决一次。(强调“只解决一次”)
  • 储存子问题的解。(强调“储存”)

例子

我们继续拿斐波那契数列来打比方。斐波那数列1 1 2 3 5 8 13 21…前两数的和是后一个数的值
左下图是使用递归来求解的写法,显然,这是一个非常低效的方法,因为其中有大量的重复计算。并且不满足动态规划的第二个特点:“所有的子问题都只需要解决一次“,这个问题很好解决,我们只需要利用动态规划的第三个特点:”储存子问题的解“就可以了。比如,如果已经计算过Fibonacci(3),那么把结果储存起来,其他地方碰到需要求Fibonacci(3)的时候,就不需要计算,直接调用结果就行。这样做之后,蓝色表示需要进行计算的,白色表示可以直接从存储中取得结果的:
在这里插入图片描述
在这里插入图片描述
递归求法

long long Fib(int n)
{
	if (n==1 || n==2)
		return 1;
	return Fib(n - 1) + Fib(n - 2);
}

f(6) = f(5)+f(4)=f(4)+f(3) +f(3)+f(2) = f(3)+f(2)+f(2)+f(1)+f(2)+f(1)+1+1…

贪心法

贪心法:总是做出在当前来说是最好的选择,而并不从整体上加以考虑,它所做的每步选择只是当前步骤的局部最优选择,但从整体来说不一定是最优的选择。由于它不比为了寻找最优解而穷尽所有可能解,因此其耗费时间少,一般可以快速得到满意的解,但得不到最优解。

局部贪心,只针对档前的步骤取最优,而非整体考虑。

判断此类算法,就看算法是否是每一步都取最优,并且整体题意没有透露出最终结果是最优的。

例子

假设你身上带了足够的1、5、10、20、50、100元面值的钞票。现在您的目标是凑出某个金额w,并且需要用到尽量少的钞票。依据生活经验,我们可以采取这样的策略:能用100的就尽量用100的,否则尽量用50的…依次类推。在这种策略下,666=6×100+1×50+1×10+1×5+1×1,共使用了10张钞票。
这种策略称为“贪心”:假设我们面对的局面是“需要凑出w”,贪心策略会尽快让w变得更小。能让w少100就尽量让它少100,这样我们接下来面对的局面就是凑出w-100。长期的生活经验表明,贪心策略是正确的。
但是,如果我们换一组钞票的面值,贪心策略就也许不成立了。如果一个奇葩国家的钞票面额分别是1、5、11,那么我们在凑出15的时候,贪心策略会出错:15=1×11+4×1(贪心策略使用了5张钞票),15=3×5(正确的策略,只用3张钞票)
为什么会这样呢?贪心策略错在了哪里?
刚刚已经说过,贪心策略的纲领是:“尽量使接下来面对的w更小”。这样,贪心策略在w=15的局面时,会优先使用11来把w降到4;但是在这个问题中,凑出4的代价是很高的,必须使用4×1。如果使用了5,w会降为10,虽然没有4那么小,但是凑出10只需要两张5元。
在这里我们发现,贪心是一种只考虑眼前情况的策略。

DP解决方法

如果直接暴力枚举凑出的方案,明显复杂度过高。太多种方法可以凑出w了,枚举它们的时间是不可承受的。我们现在来尝试找一下性质。
重新分析刚网刚的例子。w=15时,我们如果取11,接下来就面对w=4的情况;如果取5,则接下来面对w=10的情况。我们发现这些问题都有相同的形式:"给定w,凑出w所用的最少钞票是多少张?”接下来,我们用f(n)来表示“"凑出n所需的最少钞票数量”。
那么,如果我们取了11,最后的代价(用掉的钞票总数)是多少呢?
明显cost=f(4)+1=4+1=5,它的意义是:利用11来凑出15,付出的代价等于f(4)加上自己这一张钞票。现在我们暂时不管f(4)怎么求出来。
依次类推,马上可以知道:如果我们用5来凑出15,cost就是f(10)+1=2+1=3
那么,现在w=15的时候,我们该取那种钞票呢?当然是各种方案中,c0st值最低的那一个!

  • 取11:cost=f(4)+1=4+1=5
  • 取5:cost=f10)+1=2+1=3
  • 取1:cost=f(14)+1=4+1=5
    显而易见,cost值最低的是取5的方案。我们通过上面三个式子,做出了正确的决策!
    这给了我们一个至关重要的启示一一f(n)只与f(n-1),f(n-5),f(n-11)相关;更确切地说:
    f(n)=min{f(n-1),f(m-5),f(n-11)}+1
    这就是DP(动态规划,dynamic programming)
    将一个问题拆成几个子问题,分别求解这些子问题,即可推断出大问题的解。
  • 14
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

yoyo勰

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

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

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

打赏作者

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

抵扣说明:

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

余额充值