常见算法及问题场景——动态规划

版权声明:本文为农场老马原创文章,未经农场老马允许不得转载。 https://blog.csdn.net/a345017062/article/details/52411094

总述

动态规划、分治(最经典的是二分法)、贪心的共性:把问题划分为多个子问题,通过求子问题的解来求得问题最优解。
动态规划与分治的区别:动态规划的多个子问题之间是有依赖关系的,分治则没有。
动态规划与贪心的区别:动态规划求解当前子问题时,依赖于前面所有子问题的解;而贪心求当前子问题时,只考虑当前状态。

先推荐一篇讲动态规划讲得很好的文章:
http://www.hawstein.com/posts/dp-novice-to-advanced.html
接下来从几个经典问题来看。

硬币组合

问题

有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?

思路

依次计算出0~11元的组合,并记录,每一个组合是前面所有组合中的某一个与1元、3元、5元硬币的搭配,并在搭配集合中取最小的一个。

f(y) = min{f(y-1)+1,f(y-3)+1,f(y-5)+1};
1:1
2 : min{f(2-1)+1,x,x} = 1+1 = 2;
3 : min{f(3-1)+1,x,x} = 2 + 1 = 3;
4 : min{f(4-1)+1,f(4-3)+1,x} = min{f(3)+1,f(1)+1,x} = min{4,2} = 2;
5:min{f(5-1)+1,f(5-3)+1,x} = min{f(4)+1,f(2)+1,x} = min{3,3,x} = 3;
6:min{f(6-1)+1,f(6-3)+1,f(6-5)+1} = min{f(5)+1,f(3)+1,f(1)+1} = min{3,4,2} = 2;
… …

0-1背包

问题

一个贼在偷窃一家商店时发现了n件物品,其中第i件值vi元,重wi磅。他希望偷走的东西总和越值钱越好,但是他的背包只能放下W磅。请求解如何放能偷走最大价值的物品,这里vi、wi、W都是整数。

思路

如果每个物品都允许切割并只带走其一部分,则演变为部分背包问题,可以用贪心法求解。
1、把n个物品按单位价值进行降序排列。
2、按前面的降序排列,依次装入物品,并记录每一件物品装入后的剩余容量c(i)。直到装入到第k件物品的时发现超载。
3、依次查看c(k-1)~c(1),看是否可以找到剩余容量可以装入第k件物品的状态:
如果没有找到,则放弃,继续装入k+1件物品。
如果找到,则比较装入k的话,是否比c(k-1)总价值大:如果小,则放弃;如果大,则装入k。
回到第3步,继续装入k+1。

Viterbi-维特比算法

问题

在输入法的联想策略设计中,假设我输入wszs,分别代表4个字,我们需要猜测出用户想打的字是什么,可能是”我是张三”,又可能是“晚上再说”,把可能性最大的放在前面。

思路

上面问题的解决模型,都可以用下面这张图来描述
这里写图片描述
有向图的节点表示迁移状态,有向图的边表示状态间的迁移概率。
每一列的节点代表了几种不同的状态,不同列各状态之间的迁移概率大小不一。
我们要找出概率最大的那条迁移路径来。
假设x11到x21的值为v(11,21)
1、f(1)=
{len(11),len(12),len(13)}=
{0,0,0}
2、f(2)=
{len(21),len(22),len(23)}=
{min{v(11,21),v(12,21),v(13,21)},min{v(11,22),v(12,22),v(13,22)},min{v(11,23),v(12,23),v(13,23)}}
3、f(3)=
{len(31),len(32),len(33)}=
{min{v(21,31),v(22,31),v(23,31)},min{v(21,32),v(22,32),v(23,32)},min{v(21,33),v(22,33),v(23,33)}}
……
依次计算,并记录每一步的计算结果,最后求出min(f(n)),就是min{len(n1),len(n2),len(n3)}的值,即为最短路径长度。
如需列出最短路径上的节点,在每一步中记录节点的前后关系就行。

猜你喜欢

转载自blog.csdn.net/a345017062/article/details/52411094
今日推荐