How can I find the maximum sum of a sub-sequence using dynamic programming?

前端 未结 3 854
陌清茗
陌清茗 2020-12-20 15:56

I\'m re-reading Skiena\'s Algorithm Design Manual to catch up on some stuff I\'ve forgotten since school, and I\'m a little baffled by his descriptions of Dynamic Programmin

相关标签:
3条回答
  • 2020-12-20 16:11

    My understanding of DP is about "making a table". In fact, the original meaning "programming" in DP is simply about making tables.

    The key is to figure out what to put in the table, or modern terms: what state to track, or what's the vertex key/value in DAG (ignore these terms if they sound strange to you).

    How about choose dp[i] table being the largest sum ending at index i of the array, for example, the array being [5, 15, -30, 10]

    The second important key is "optimal substructure", that is to "assume" dp[i-1] already stores the largest sum for sub-sequences ending at index i-1, that's why the only step at i is to decide whether to include a[i] into the sub-sequence or not

    dp[i] = max(dp[i-1], dp[i-1] + a[i])
    

    The first term in max is to "not include a[i]", the second term is to "include a[i]". Notice, if we don't include a[i], the largest sum so far remains dp[i-1], which comes from the "optimal substructure" argument.

    So the whole program looks like this (in Python):

    a = [5,15,-30,10]
    
    dp = [0]*len(a)
    dp[0] = max(0,a[0]) # include a[0] or not
    
    for i in range(1,len(a)):
        dp[i] = max(dp[i-1], dp[i-1]+a[i]) # for sub-sequence, choose to add or not     
    
    
     print(dp, max(dp)) 
    

    The result: largest sum of sub-sequence should be the largest item in dp table, after i iterate through the array a. But take a close look at dp, it holds all the information.

    Since it only goes through items in array a once, it's a O(n) algorithm.

    This problem seems silly, because as long as a[i] is positive, we should always include it in the sub-sequence, because it will only increase the sum. This intuition matches the code

    dp[i] = max(dp[i-1], dp[i-1] + a[i])
    

    So the max. sum of sub-sequence problem is easy, and doesn't need DP at all. Simply,

    sum = 0
    for v in a:
         if  v >0
             sum += v
    

    However, what about largest sum of "continuous sub-array" problem. All we need to change is just a single line of code

    dp[i] = max(dp[i-1]+a[i], a[i])    
    

    The first term is to "include a[i] in the continuous sub-array", the second term is to decide to start a new sub-array, starting a[i].

    In this case, dp[i] is the max. sum continuous sub-array ending with index-i.

    This is certainly better than a naive approach O(n^2)*O(n), to for j in range(0,i): inside the i-loop and sum all the possible sub-arrays.

    One small caveat, because the way dp[0] is set, if all items in a are negative, we won't select any. So for the max sum continuous sub-array, we change that to

    dp[0] = a[0]
    
    0 讨论(0)
  • 2020-12-20 16:14

    You should take a look to this pdf back in the school in http://castle.eiu.edu here it is:

    enter image description here

    The explanation of the following pseudocode is also int the pdf. enter image description here

    0 讨论(0)
  • 2020-12-20 16:29

    There is a solution like, first sort the array in to some auxiliary memory, then apply Longest Common Sub-Sequence method to the original array and the sorted array, with sum(not the length) of common sub-sequence in the 2 arrays as the entry into the table (Memoization). This can also solve the problem

    Total running time is O(nlogn)+O(n^2) => O(n^2) Space is O(n) + O(n^2) => O(n^2)

    This is not a good solution when memory comes into picture. This is just to give a glimpse on how problems can be reduced to one another.

    0 讨论(0)
提交回复
热议问题