============================ Dynamic Programming ===============================
斐波那契
f[i]:第i个的值
70. Climbing Stairs(1或2步爬楼梯)
f[i]=f[i-1]+f[i-2];
91. Decode Ways(编码方式的个数)
int tmp=((s[i-1]-'0')*10+s[i]-'0');
if (tmp>=10 && tmp<=26) f[i+1]+=f[i-1];
338. Counting Bits(1-n,返回每个数二进制1的个数)
Discuss: f[i] = f[i / 2] + i % 2.
for (int i=1; i<=num; i++) f[i] = f[i >> 1] + (i & 1);
左上->右下
f[i][j]:到达(i,j)位置,且一定用(i,j)的最佳
62. Unique Paths(有多少种方法)
S1(Mine): DP f[i][j]:到达(i,j)点方法数。f[i][j] = f[i-1][j] + f[i][j-1];
S2(Discuss): 组合数
63. Unique Paths II(有障碍,多少种方法)
同62,标记障碍即可
64. Minimum Path Sum(和最小)
DP: S[i][j] = min(S[i - 1][j], S[i][j - 1]) + grid[i][j]
120. Triangle(三角形,从上到下找最短路径)
triangle[i][j]+=min(triangle[i+1][j],triangle[i+1][j+1]);
174. Dungeon Game
Discuss:
最难的一个方格取数
Use hp[i][j] to store the min hp needed at position (i, j), then do the calculation
from right-bottom to left-up.
Note: adding dummy row and column would make the code cleaner.
Discuss hp[i][j]表示的是,(i,j)位置需要的最少血量;
然后倒着循环;
并且在计算hp[i][j]时,如果>0 则1,小于0,则血量
矩阵
常用的就是(i-1,j) (i,j-1) (i-1,j-1) 以及(i,j) 各种加加减减
85. Maximal Rectangle(找到全部为1的最大矩阵)
每个点的情况,是由它的上,左,左上决定的。
三个变量: left, right, height
height:counts the number of successive '1's above (plus the current one).
方程
left & right: means the boundaries of the rectangle which contains the current point with a height of value height.
left(i,j) = max(left(i-1,j), cur_left), cur_left can be determined from the current row
right(i,j) = min(right(i-1,j), cur_right), cur_right can be determined from the current row
height(i,j) = height(i-1,j) + 1, if matrix[i][j]=='1';
height(i,j) = 0, if matrix[i][j]=='0'
304. Range Sum Query 2D - Immutable(多次查询矩阵中某个小矩阵的和)
Discuss:sum[i][j]: 左上角到(i,j)的矩阵和,sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+matrix[i-1][j-1];
求值时,直接返回sum的加减公式即可。
row1++;col1++;row2++;col2++;
return sum[row2][col2]+sum[row1-1][col1-1]-sum[row2][col1-1]-sum[row1-1][col2];
sell & buy
release[i],hold[i],k>=n/2
121. Best Time to Buy and Sell Stock(1次交易)
维护当前最小费用和最大利润,更新。
122. Best Time to Buy and Sell Stock II(多次交易)
只要比前一个大,就累计
if (prices[i]-prices[i-1]>0)ans += prices[i]-prices[i-1];
123. Best Time to Buy and Sell Stock III(两次交易)
188. Best Time to Buy and Sell Stock IV(k次交易)
k >= n/2时,最大次数交易->122
release[i]: when release the ith transaction, the maximum
hold[i]: when hold the ith transaction, the maximum
release[j]=max(release[j],hold[j]+prices[i]);
hold[j]=max(hold[j],release[j-1]-prices[i]);
ans=max(ans,release[j]);
309. Best Time to Buy and Sell Stock with Cooldown(买卖任意次数,卖和买之前至少间隔一天)
Discuss: 仍旧是记录下之前买和卖的价格,然后让间隔就间隔的去找max
LCS
f[i]以i为尾,一定包含i时的xxx
334. Increasing Triplet Subsequence(长度为3的升串是否存在)
朴素LCS
53. Maximum Subarray(找到和最大的连续子串)
DP f[i]:以i为尾,且包含i的最大和。 f[i]=max(nums[i],f[i-1]+nums[i])
300. Longest Increasing Subsequence
128. Longest Consecutive Sequence(无序数,找到最长连续数列)
S1(Mine):朴素,用map记录是否出现过。
S2(Discuss):Set,把数丢进set,遍历,如果当前i是头(i-1不在set),则往后直到不连续,update max值
354. Russian Doll Envelopes(二维LCS,长和宽)
198. House Robber(连续两家不能同时被盗,求最大值)
result[i] = max(result[i-1],result[i-2]+num[i-1]);
对于i: (1)选它和隔一个前面 (2)不选他,选他前一个
213. House Robber II(变成一个圈)
Mine: 依次遍历起始点即可。
238. Product of Array Except Self(给定一个数组,返回第i位是所有其他的乘积)
left[i],right[i]:左边和右边连续乘积
ans[i] = left[i]*right[i+2];
152. Maximum Product Subarray(找到乘积最大的子串)
max和min分别记录当前的最大乘积和最小乘积。乘以负数时,交换两个
53. Maximum Subarray(连续子串和最大)
f[i]:以i为尾,且包含i的最大和。f[i]=max(nums[i],f[i-1]+nums[i]);
368. Largest Divisible Subset(找到最大的子集,是的每个数都是其他所有数的约数或者倍数)
Discuss: 从小到大排序,f[i]以i为尾,且包含i的最多的个数;route[i]:最大的i是从谁来的,记录更新路径
f[n] = the length of the largest divisible subset whose largest number is a[n]
f[n+1] = max{ 1 + f[i] if a[n+1] mod a[i] == 0 else 1 }
139. Word Break(根据字典,把字符串拆成字典中的单词)
Mine: convert the dic words according to the string s to vector of intervals
then, sort the intervals, and mark the points that can be reached.
0. Using eg s="leetcode", wordDict = ["leet","code"]
1. Search every word in to string s, calculate the intervals it can cover, eg: the intervals vector is [0,3],[4,7]
2. Sort the vector by the values of .start
3. for each interval point, like [4,7], if its previous point can be reached,
then the current interval.start can be reached, for
then mark the interval.end point as can be reached.
140. Word Break II(字典和串,找到所有拆分的结果)
Mine: 在139的基础上,记录路径即可。
1. vector< vector<int> > record;
record[i][j]: for the location i in string s, which intervals can reach to this point;
for location i, interval j can reach to it.
record[i][j] is the index of intervals
2. vector<int> trace;
trace[i]: th ith interval that used to form the route.
trace[i] is the index of intervals
3. add string word to struct Interval
329. Longest Increasing Path in a Matrix(求一个矩形的最长下降路径)
Mine: 转成LCS,每个节点,记录值,坐标,然后排序,转换成LCS,只有坐标挨着才能更新f[i]
感觉自己好屌比好聪明啊!
376. Wiggle Subsequence(给定一串数,返回最长的山峰序列)
Mine: if (nums[j]<nums[i]) fn[i]=max(fp[i],fn[j]+1);
if (nums[j]>nums[i]) fn[i]=max(fn[i],fp[j]+1);
两串添加删除变换
f[i][j]:串A前i位,串B前j位
A[i]==B[j];A[i]!=B[j]
72. Edit Distance(两串,添加,删除,变换,最少步骤一样)
if c == d, then : f[i][j] = f[i-1][j-1]
else f[i][j]=min(f[i-1][j-1] + 1,f[i][j] = f[i][j-1] + 1,f[i-1][j] + 1)
97. Interleaving String(两个串s1 s2,有序穿插从里面选,生成s3)
DP table represents if s3 is interleaving at (i+j)th position when s1 is at ith position,
and s2 is at jth position. 0th position means empty string.
So if both s1 and s2 is currently empty, s3 is empty too, and it is considered interleaving.
If only s1 is empty, then if previous s2 position is interleaving and current s2 position char
is equal to s3 current position char, it is considered interleaving. similar idea applies to
when s2 is empty. when both s1 and s2 is not empty, then if we arrive i, j from i-1, j, then
if i-1,j is already interleaving and i and current s3 position equal, it s interleaving.
If we arrive i,j from i, j-1, then if i, j-1 is already interleaving and j and current
s3 position equal. it is interleaving.
115. Distinct Subsequences(找到两串相同子序列的个数)
Discuss:dp[i][j] to be the number of distinct subsequences of t[0..i - 1] in s[0..j - 1]. d
General case 1: dp[i][j] = dp[i][j - 1] if t[i - 1] != s[j - 1];
General case 2: dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1] if t[i - 1] == s[j - 1];
Boundary case 1: dp[0][j] = 1 for all j;
Boundary case 2: dp[i][0] = 0 for all positive i.
括号
f[i]以i为尾且一定包含i的情况
32. Longest Valid Parentheses(找到最长的合法括号的子串)
s[i]: 以i为尾包含i的最长的合法子串。
If s[i] is '(', set longest[i] to 0,because any string end with '(' cannot be a valid one.
If s[i] is ')'
If s[i-1] is '(', longest[i] = longest[i-2] + 2
If s[i-1] is ')' and s[i-longest[i-1]-1] == '(', longest[i] = longest[i-1] + 2 + longest[i-longest[i-1]-2]
背包问题
279. Perfect Squares(给定一个n,找到最少个数的平方数,使得它们的和为n)
01背包,平方数是物品,n是容量,求最少的物品个数
322. Coin Change(换硬币)
完全背包问题
377. Combination Sum IV
在某区间遍历mid
for i = start -> end:
deal(start,i-1);deal(i+1,end); implement i;
95. Unique Binary Search Trees II(给定一个整数n,求出所有结构的平衡二叉树,1..n)
for(int i=s;i<=e;i++)
{left=bisearch(s,i-1);right=bisearch(i+1,e);}
96. Unique Binary Search Trees(个数)
F(i, n) = G(i-1) * G(n-i)
132. Palindrome Partitioning II
The definition of 'cut' array is the minimum number of cuts of a sub string. More specifically,
cut[n] stores the cut number of string s[0, n-1].
Initialize the 'cut' array: For a string with n characters s[0, n-1], it needs at most n-1 cut.
Therefore, the 'cut' array is initialized as cut[i] = i-1
Use two variables in two loops to represent a palindrome:
The external loop variable 'i' represents the center of the palindrome.
The internal loop variable 'j' represents the 'radius' of the palindrome. Apparently, j <= i is a must.
This palindrome can then be represented as s[i-j, i+j]. If this string is indeed a palindrome,
then one possible value of cut[i+j] is cut[i-j] + 1, where cut[i-j] corresponds to s[0, i-j-1] and 1
correspond to the palindrome s[i-j, i+j];
124. Binary Tree Maximum Path Sum(返回二叉树的最长路径和)
S(Mine): the node value can be zero and negative
1. 设置一个函数f[node](代码中用的int maxLeafInlucdeRoot(TreeNode* root))
从下往上,以node为尾且包含node的最大和。
f[node]=max(node->val, node->val+ f[lchild],node->val+f[rchild])
// node点自己;node和左儿子;node和右儿子
2. 在计算f[node]的过程中,更新全局变量res,每次求最大值
res=max(res, f[node], node->val + f[lchild] + f[rchild])
// res自己;已经求出的f[node],即单路径; node自己值+左儿子最大+右儿子最大,即以node为根折叠的值
87. Scramble String(把一个串分两部分作为左右儿子,且儿子可交换,生成一棵二叉树,判断s2是不是s1的这种生成的)
Mine: 这道题貌似费了好长时间自己做出来,好开心的。
在区间找到mid,循环mid进行分割
将s1和s2分别分割,然后递归进行比对。
判断两串是否相同:bool sameLetters(string s1,string s2)
isScramble(left1,left2)&&isScramble(right1,right2);
isScramble(left1,right2)&&isScramble(right1,left2);
241. Different Ways to Add Parentheses(不同添加括号的方式,求所有可能的计算结果)
Mine: 循环i,diffWaysToCompute(input.substr(0,i));
diffWaysToCompute(input.substr(i+1));
区间大小递增,2,3,4,5,6……
312. Burst Balloons(一排带数的气球,弄爆所有的最大值,结果为弄爆气球的和x_left * x * x_right)
Discuss: 外层循环k->[2,n),区间的大小k,计算left和right,在[left,right]区间遍历i
max(爆i,不爆i)。dp[left][right]=max(dp[left][right],num[left]*num[i]*num[right]+dp[left][i]+dp[i][right]);
两串穿插
321. Create Maximum Number(两串数只有0..9,交叉组成新的数串,求最大)
Discuss:分别用array1生成长度为k的最大串,array2生成长度为n-k的最大串,然后合并。
k-1的最大串,由k串删掉一个书生成。
斐波那契
f[i]:第i个的值
70. Climbing Stairs(1或2步爬楼梯)
f[i]=f[i-1]+f[i-2];
91. Decode Ways(编码方式的个数)
int tmp=((s[i-1]-'0')*10+s[i]-'0');
if (tmp>=10 && tmp<=26) f[i+1]+=f[i-1];
338. Counting Bits(1-n,返回每个数二进制1的个数)
Discuss: f[i] = f[i / 2] + i % 2.
for (int i=1; i<=num; i++) f[i] = f[i >> 1] + (i & 1);
左上->右下
f[i][j]:到达(i,j)位置,且一定用(i,j)的最佳
62. Unique Paths(有多少种方法)
S1(Mine): DP f[i][j]:到达(i,j)点方法数。f[i][j] = f[i-1][j] + f[i][j-1];
S2(Discuss): 组合数
63. Unique Paths II(有障碍,多少种方法)
同62,标记障碍即可
64. Minimum Path Sum(和最小)
DP: S[i][j] = min(S[i - 1][j], S[i][j - 1]) + grid[i][j]
120. Triangle(三角形,从上到下找最短路径)
triangle[i][j]+=min(triangle[i+1][j],triangle[i+1][j+1]);
174. Dungeon Game
Discuss:
最难的一个方格取数
Use hp[i][j] to store the min hp needed at position (i, j), then do the calculation
from right-bottom to left-up.
Note: adding dummy row and column would make the code cleaner.
Discuss hp[i][j]表示的是,(i,j)位置需要的最少血量;
然后倒着循环;
并且在计算hp[i][j]时,如果>0 则1,小于0,则血量
矩阵
常用的就是(i-1,j) (i,j-1) (i-1,j-1) 以及(i,j) 各种加加减减
85. Maximal Rectangle(找到全部为1的最大矩阵)
每个点的情况,是由它的上,左,左上决定的。
三个变量: left, right, height
height:counts the number of successive '1's above (plus the current one).
方程
left & right: means the boundaries of the rectangle which contains the current point with a height of value height.
left(i,j) = max(left(i-1,j), cur_left), cur_left can be determined from the current row
right(i,j) = min(right(i-1,j), cur_right), cur_right can be determined from the current row
height(i,j) = height(i-1,j) + 1, if matrix[i][j]=='1';
height(i,j) = 0, if matrix[i][j]=='0'
304. Range Sum Query 2D - Immutable(多次查询矩阵中某个小矩阵的和)
Discuss:sum[i][j]: 左上角到(i,j)的矩阵和,sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+matrix[i-1][j-1];
求值时,直接返回sum的加减公式即可。
row1++;col1++;row2++;col2++;
return sum[row2][col2]+sum[row1-1][col1-1]-sum[row2][col1-1]-sum[row1-1][col2];
sell & buy
release[i],hold[i],k>=n/2
121. Best Time to Buy and Sell Stock(1次交易)
维护当前最小费用和最大利润,更新。
122. Best Time to Buy and Sell Stock II(多次交易)
只要比前一个大,就累计
if (prices[i]-prices[i-1]>0)ans += prices[i]-prices[i-1];
123. Best Time to Buy and Sell Stock III(两次交易)
188. Best Time to Buy and Sell Stock IV(k次交易)
k >= n/2时,最大次数交易->122
release[i]: when release the ith transaction, the maximum
hold[i]: when hold the ith transaction, the maximum
release[j]=max(release[j],hold[j]+prices[i]);
hold[j]=max(hold[j],release[j-1]-prices[i]);
ans=max(ans,release[j]);
309. Best Time to Buy and Sell Stock with Cooldown(买卖任意次数,卖和买之前至少间隔一天)
Discuss: 仍旧是记录下之前买和卖的价格,然后让间隔就间隔的去找max
LCS
f[i]以i为尾,一定包含i时的xxx
334. Increasing Triplet Subsequence(长度为3的升串是否存在)
朴素LCS
53. Maximum Subarray(找到和最大的连续子串)
DP f[i]:以i为尾,且包含i的最大和。 f[i]=max(nums[i],f[i-1]+nums[i])
300. Longest Increasing Subsequence
128. Longest Consecutive Sequence(无序数,找到最长连续数列)
S1(Mine):朴素,用map记录是否出现过。
S2(Discuss):Set,把数丢进set,遍历,如果当前i是头(i-1不在set),则往后直到不连续,update max值
354. Russian Doll Envelopes(二维LCS,长和宽)
198. House Robber(连续两家不能同时被盗,求最大值)
result[i] = max(result[i-1],result[i-2]+num[i-1]);
对于i: (1)选它和隔一个前面 (2)不选他,选他前一个
213. House Robber II(变成一个圈)
Mine: 依次遍历起始点即可。
238. Product of Array Except Self(给定一个数组,返回第i位是所有其他的乘积)
left[i],right[i]:左边和右边连续乘积
ans[i] = left[i]*right[i+2];
152. Maximum Product Subarray(找到乘积最大的子串)
max和min分别记录当前的最大乘积和最小乘积。乘以负数时,交换两个
53. Maximum Subarray(连续子串和最大)
f[i]:以i为尾,且包含i的最大和。f[i]=max(nums[i],f[i-1]+nums[i]);
368. Largest Divisible Subset(找到最大的子集,是的每个数都是其他所有数的约数或者倍数)
Discuss: 从小到大排序,f[i]以i为尾,且包含i的最多的个数;route[i]:最大的i是从谁来的,记录更新路径
f[n] = the length of the largest divisible subset whose largest number is a[n]
f[n+1] = max{ 1 + f[i] if a[n+1] mod a[i] == 0 else 1 }
139. Word Break(根据字典,把字符串拆成字典中的单词)
Mine: convert the dic words according to the string s to vector of intervals
then, sort the intervals, and mark the points that can be reached.
0. Using eg s="leetcode", wordDict = ["leet","code"]
1. Search every word in to string s, calculate the intervals it can cover, eg: the intervals vector is [0,3],[4,7]
2. Sort the vector by the values of .start
3. for each interval point, like [4,7], if its previous point can be reached,
then the current interval.start can be reached, for
then mark the interval.end point as can be reached.
140. Word Break II(字典和串,找到所有拆分的结果)
Mine: 在139的基础上,记录路径即可。
1. vector< vector<int> > record;
record[i][j]: for the location i in string s, which intervals can reach to this point;
for location i, interval j can reach to it.
record[i][j] is the index of intervals
2. vector<int> trace;
trace[i]: th ith interval that used to form the route.
trace[i] is the index of intervals
3. add string word to struct Interval
329. Longest Increasing Path in a Matrix(求一个矩形的最长下降路径)
Mine: 转成LCS,每个节点,记录值,坐标,然后排序,转换成LCS,只有坐标挨着才能更新f[i]
感觉自己好屌比好聪明啊!
376. Wiggle Subsequence(给定一串数,返回最长的山峰序列)
Mine: if (nums[j]<nums[i]) fn[i]=max(fp[i],fn[j]+1);
if (nums[j]>nums[i]) fn[i]=max(fn[i],fp[j]+1);
两串添加删除变换
f[i][j]:串A前i位,串B前j位
A[i]==B[j];A[i]!=B[j]
72. Edit Distance(两串,添加,删除,变换,最少步骤一样)
if c == d, then : f[i][j] = f[i-1][j-1]
else f[i][j]=min(f[i-1][j-1] + 1,f[i][j] = f[i][j-1] + 1,f[i-1][j] + 1)
97. Interleaving String(两个串s1 s2,有序穿插从里面选,生成s3)
DP table represents if s3 is interleaving at (i+j)th position when s1 is at ith position,
and s2 is at jth position. 0th position means empty string.
So if both s1 and s2 is currently empty, s3 is empty too, and it is considered interleaving.
If only s1 is empty, then if previous s2 position is interleaving and current s2 position char
is equal to s3 current position char, it is considered interleaving. similar idea applies to
when s2 is empty. when both s1 and s2 is not empty, then if we arrive i, j from i-1, j, then
if i-1,j is already interleaving and i and current s3 position equal, it s interleaving.
If we arrive i,j from i, j-1, then if i, j-1 is already interleaving and j and current
s3 position equal. it is interleaving.
115. Distinct Subsequences(找到两串相同子序列的个数)
Discuss:dp[i][j] to be the number of distinct subsequences of t[0..i - 1] in s[0..j - 1]. d
General case 1: dp[i][j] = dp[i][j - 1] if t[i - 1] != s[j - 1];
General case 2: dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1] if t[i - 1] == s[j - 1];
Boundary case 1: dp[0][j] = 1 for all j;
Boundary case 2: dp[i][0] = 0 for all positive i.
括号
f[i]以i为尾且一定包含i的情况
32. Longest Valid Parentheses(找到最长的合法括号的子串)
s[i]: 以i为尾包含i的最长的合法子串。
If s[i] is '(', set longest[i] to 0,because any string end with '(' cannot be a valid one.
If s[i] is ')'
If s[i-1] is '(', longest[i] = longest[i-2] + 2
If s[i-1] is ')' and s[i-longest[i-1]-1] == '(', longest[i] = longest[i-1] + 2 + longest[i-longest[i-1]-2]
背包问题
279. Perfect Squares(给定一个n,找到最少个数的平方数,使得它们的和为n)
01背包,平方数是物品,n是容量,求最少的物品个数
322. Coin Change(换硬币)
完全背包问题
377. Combination Sum IV
在某区间遍历mid
for i = start -> end:
deal(start,i-1);deal(i+1,end); implement i;
95. Unique Binary Search Trees II(给定一个整数n,求出所有结构的平衡二叉树,1..n)
for(int i=s;i<=e;i++)
{left=bisearch(s,i-1);right=bisearch(i+1,e);}
96. Unique Binary Search Trees(个数)
F(i, n) = G(i-1) * G(n-i)
132. Palindrome Partitioning II
The definition of 'cut' array is the minimum number of cuts of a sub string. More specifically,
cut[n] stores the cut number of string s[0, n-1].
Initialize the 'cut' array: For a string with n characters s[0, n-1], it needs at most n-1 cut.
Therefore, the 'cut' array is initialized as cut[i] = i-1
Use two variables in two loops to represent a palindrome:
The external loop variable 'i' represents the center of the palindrome.
The internal loop variable 'j' represents the 'radius' of the palindrome. Apparently, j <= i is a must.
This palindrome can then be represented as s[i-j, i+j]. If this string is indeed a palindrome,
then one possible value of cut[i+j] is cut[i-j] + 1, where cut[i-j] corresponds to s[0, i-j-1] and 1
correspond to the palindrome s[i-j, i+j];
124. Binary Tree Maximum Path Sum(返回二叉树的最长路径和)
S(Mine): the node value can be zero and negative
1. 设置一个函数f[node](代码中用的int maxLeafInlucdeRoot(TreeNode* root))
从下往上,以node为尾且包含node的最大和。
f[node]=max(node->val, node->val+ f[lchild],node->val+f[rchild])
// node点自己;node和左儿子;node和右儿子
2. 在计算f[node]的过程中,更新全局变量res,每次求最大值
res=max(res, f[node], node->val + f[lchild] + f[rchild])
// res自己;已经求出的f[node],即单路径; node自己值+左儿子最大+右儿子最大,即以node为根折叠的值
87. Scramble String(把一个串分两部分作为左右儿子,且儿子可交换,生成一棵二叉树,判断s2是不是s1的这种生成的)
Mine: 这道题貌似费了好长时间自己做出来,好开心的。
在区间找到mid,循环mid进行分割
将s1和s2分别分割,然后递归进行比对。
判断两串是否相同:bool sameLetters(string s1,string s2)
isScramble(left1,left2)&&isScramble(right1,right2);
isScramble(left1,right2)&&isScramble(right1,left2);
241. Different Ways to Add Parentheses(不同添加括号的方式,求所有可能的计算结果)
Mine: 循环i,diffWaysToCompute(input.substr(0,i));
diffWaysToCompute(input.substr(i+1));
区间大小递增,2,3,4,5,6……
312. Burst Balloons(一排带数的气球,弄爆所有的最大值,结果为弄爆气球的和x_left * x * x_right)
Discuss: 外层循环k->[2,n),区间的大小k,计算left和right,在[left,right]区间遍历i
max(爆i,不爆i)。dp[left][right]=max(dp[left][right],num[left]*num[i]*num[right]+dp[left][i]+dp[i][right]);
两串穿插
321. Create Maximum Number(两串数只有0..9,交叉组成新的数串,求最大)
Discuss:分别用array1生成长度为k的最大串,array2生成长度为n-k的最大串,然后合并。
k-1的最大串,由k串删掉一个书生成。