动态规划是一种实用的技巧,它可以用来解决一系列特定问题。它的思路很简单,如果你对某个给定的输入解决了一个问题,那么你可以保存已有信息,以避免重复计算,节约计算时间。
记住,只有那些没有办法记住历史的才被迫做更多的苦力。(Fibonacci就是一个显然的例子)
最长上升子序列问题。给定S= {a[1] , a[2] , a[3], a[4], ............., a[n-1], a[n] },求出一个子序列,使得对于所有在这个子序列中所有满足j<i的j与i,满足aj<ai。首先我们要讨论以原序列的第i个元素结尾的最长上升子序列dp[i]。那么答案是整个dp序列的最大值。考虑dp[i],它的最后一个元素为a[i]。枚举它的倒数第二个元素a[j],则a[j]<a[i]成立。则dp[i]就是所有这样的dp[j]的最大值加上1(最后一个元素)。这个算法具有O(n^2)的时间复杂度。
此算法的伪代码:
for i=0 to n-1 dp[i]=0 for j=0 to i-1 if (a[i] > a[j] and dp[i]<dp[j]) LS[i] = LS[j] dp[i]=dp[i]+1for i=0 to n-1 if (largest < dp[i]) largest = dp[i]这个算法的复杂度可以通过将数组换为其他数据结构来优化,来获得*O(n * log n)*的时间复杂度。
同样的思路可以求出有向无环图上的最大路径。