我们经常遇到这样的问题:
多个元素之间有许多安排,让我们选择满足特定条件的最佳安排。
例如:
这些问题最简单的想法是列举所有情况,然后进行验证和比较。
例如,第一个问题:
我们可以列举所有子键,然后确定它是否是骨干字符串,并记录最长的骨干字符串。
第二个问题:
您可以列举所有组合方案,然后用满足权重的重量小于某个值的重量的最大值验证解决方案。
这是最容易考虑所有布置的组合,然后按顺序验证和比较。这样解决了许多问题。
但是,某些简单方案的业务需求还可以。
为什么?
第一个问题解决方案是枚举所有子弦,这需要所有起点和终点的坐标,然后确定它是否是骨干字符串。
这需要2个重循环来列举子弦,1个重循环,以确定是否返回文本并与最大值进行比较。
这就是O(n^3)的复杂性。
第二个问题的解决方案需要所有组合。每个项目都有两种情况:选择而不是选择。需要是递归n时间来计算所有情况,也就是说,存在2^n的情况,这些情况是李子。计算组合方法以计算M IT对象的值。
也就是说,O(2^n * m)的复杂性。
这是解决业务问题的解决方案吗?是的,实际上,在许多情况下,我们使用这种简单而简单的思考来解决问题,但是一旦数据的规模升高,这些解决方案就不会可行请参阅下图:
当数据量表相对较大时,需要具有较低时间复杂性的算法。
如何降低时间复杂性?
我们不时列举,然后单独判断:
每种情况都必须这样做,因此组合越多,复杂性就越高。
您能找到各种组合之间的法律吗?例如,如果您可以在一种情况下介绍另一种情况,您是否需要每次验证它?
例如,huiwen字符串的问题,如果我们知道我和j是偏斜的字符串,如果两个字符在之前和之后相等,那么i-1不是从j+1发出的吗?
因此,您可以找到这种派生关系:
这种推论关系后有什么变化?我们不需要列举每种情况并单独验证它。从初始情况中得出所有后续情况是否足够?
直接从结果中驱动,因此复杂性突然从O(n^3)降低到O(n)。
该算法根据初始状态从初始状态衍生出所有状态。
如果背包问题可以找到结果之间的派生关系,则无需枚举 +验证,并且可以直接推动。
让我们尝试找到:
我们担心我的项目。当可用容量为J时,最大值是多少?
那么I-1项目与I-1项目之间有什么关系?只是假装是什么。
如果可用容量J的权衡容量小于第一项的重量,则无法安装它。
那是
如果可用容量J大于I对象的重量,则可以安装它。
如果您可以安装它,则可以将其分为两种假装且不安装的情况。带更大的一个:
这是第一项和I-1项目之间的关系:
列出此状态传输方程后,它可以从初始状态中得出所有状态,然后取下符合容量W的n个项目的最大值。
复杂性已从O(2^n m)降低到O(n m)。
当遇到来自多种组合的组合组合时,总体想法是枚举 +验证,但是该思想算法具有很高的复杂性和差的性能。
如果您可以找到各种组合情况之间的派生关系,则可以直接得出它,例如i到j+1至j+1之间的返回字符串之间的关系,例如我反对容量的最大值之间的关系J和I-1项目的能力是J。
这个想法称为动态计划算法。
动态计划的困难是找到I和I-1的推导关系,即列出状态转移方程。
一旦阐明了状态传输方程,即每种组合的结果(状态)之间的派生关系,您可以从初始状态得出所有以下状态。它可以大大降低简单算法的复杂性并改善几个幅度的幅度。