[Algo] Maximum Expression Value 表达式最大值 - SegmentFault



[Algo] Maximum Expression Value 表达式最大值 - SegmentFault

给定一个整数数组,要求在数字之间任意添加乘号,加号和括号,使得最后表达式结果最大。比如1121,最大值为(1+1)*(2+1),所有数字都是正数。

动态规划

复杂度

时间O(n^2) 空间O(N^2)

思路

先假设没有乘号,那最大值就是所有数加起来,然后我们考虑将其分段加入乘号,如果某一段是加号,和其他段相乘,那我们就认为那段加号的就被加了个括号。所以我们分段的过程其实就加了括号了。但是这么多数字我们可以分很多不同段,如果用搜索的话难免会有重复计算,所以这里用到动态规划,假设dp[i][j]表示总长为i的一段数字,其中前j长的哪一段中可以包含乘号,所能产生的最大值,这么一来,假设题目所给的数字有n个,那dp[n][n]就是这所有的数字组合起来既有加号又有乘号的式子的最大值了。再假设sum(k, i)表示所给数字从第k个到第i个数字的和。递推式为dp[i][j] = max(dp[i][j], dp[k][j - 1] * sum(k + 1, i)),这里i >= k >= j。其中后半部分dp[k][j - 1] * sum(k + 1, i)表示,我们把总长为i的数字分割成前k个,和k + 1到最后两部分。前半部分最大值已知,我们用它来乘以后半部分的和,用这种方法来决定哪一段只用加号。
举例说明,假设所给数字为

3 2 6

我们可以有最大值3 * 2 * 6 = 36,一开始我们有:

sum: 3 5 11           j=0  j=1  j=2  j=3 dp:  i=0  0    0    0    0      i=1  0    3    0    0      i=2  0    5    0    0      i=3  0    11   0    0

由于总长为i,其中前1位数字可以包含乘号的情况,就是所有数字都不包含乘号,所以最大值就是累加值。然后我们看总长为2开始(总长为1就是第一个数,没有计算的必要),前2位数字可以包含乘号的情况,这里我们可以有分割点k = 1时,是3 + 2 = 5k = 2时是3 * 2 = 6两种情况(k表示从第k位开始只有加号)。这时最大值6,更新dp[2][2]

          j=0  j=1  j=2  j=3 dp:  i=0  0    0    0    0      i=1  0    3    0    0      i=2  0    5    6    0      i=3  0    11   0    0

然后我们看总长为3开始(总长为1就是第一个数,没有计算的必要),前2位数字可以包含乘号的情况。这里k=2时,3 * (2 + 6) = 24, k=3时,6 * 6 = 36(第一个6是dp[2][2],第二个6是我们所给数字中的6)

          j=0  j=1  j=2  j=3 dp:  i=0  0    0    0    0      i=1  0    3    0    0      i=2  0    5    6    0      i=3  0    11   24   36

更新完dp[3][3]我们也就计算完所有情况了,这时可知最大值是36.

注意

全局最大max在第一个用于累加的for循环后,要置为dp[n][0],否则我们会把全部数字加起来这个组合给漏掉。


Read full article from [Algo] Maximum Expression Value 表达式最大值 - SegmentFault


No comments:

Post a Comment

Labels

Algorithm (219) Lucene (130) LeetCode (97) Database (36) Data Structure (33) text mining (28) Solr (27) java (27) Mathematical Algorithm (26) Difficult Algorithm (25) Logic Thinking (23) Puzzles (23) Bit Algorithms (22) Math (21) List (20) Dynamic Programming (19) Linux (19) Tree (18) Machine Learning (15) EPI (11) Queue (11) Smart Algorithm (11) Operating System (9) Java Basic (8) Recursive Algorithm (8) Stack (8) Eclipse (7) Scala (7) Tika (7) J2EE (6) Monitoring (6) Trie (6) Concurrency (5) Geometry Algorithm (5) Greedy Algorithm (5) Mahout (5) MySQL (5) xpost (5) C (4) Interview (4) Vi (4) regular expression (4) to-do (4) C++ (3) Chrome (3) Divide and Conquer (3) Graph Algorithm (3) Permutation (3) Powershell (3) Random (3) Segment Tree (3) UIMA (3) Union-Find (3) Video (3) Virtualization (3) Windows (3) XML (3) Advanced Data Structure (2) Android (2) Bash (2) Classic Algorithm (2) Debugging (2) Design Pattern (2) Google (2) Hadoop (2) Java Collections (2) Markov Chains (2) Probabilities (2) Shell (2) Site (2) Web Development (2) Workplace (2) angularjs (2) .Net (1) Amazon Interview (1) Android Studio (1) Array (1) Boilerpipe (1) Book Notes (1) ChromeOS (1) Chromebook (1) Codility (1) Desgin (1) Design (1) Divide and Conqure (1) GAE (1) Google Interview (1) Great Stuff (1) Hash (1) High Tech Companies (1) Improving (1) LifeTips (1) Maven (1) Network (1) Performance (1) Programming (1) Resources (1) Sampling (1) Sed (1) Smart Thinking (1) Sort (1) Spark (1) Stanford NLP (1) System Design (1) Trove (1) VIP (1) tools (1)

Popular Posts