312. Burst Balloons
题目链接:https://leetcode.com/problems...
这题的dp方程还是挺难想的。首先subproblem比较容易:dp[i][j]: max coins I can get if there are balloons (i, j) left
,有n^2
个subproblem。接下来就是方程的问题了。
首先肯定是要遍历切分点:k,然后max找使coin最大的切分点,容易想到这个切分点表示的是扎破气球的位置。但是如果选择这个位置作为区间(i, j)里面第一次扎破气球的位置,问题就来了,扎破k之后,区间(i, j)内部需要合并,一个式子看起来是没法做的。所以转换一下思路,设k是区间内最后一个扎破的气球,那么问题就简单多了。k是区间内最后一个的话,k现在相邻的点就是i-1和j+1了,注意如果i = 0, j = n-1,要单独讨论下,还有分割点可以取左右边界i或者j。
public class Solution {
public int maxCoins(int[] nums) {
int n = nums.length;
if(n == 0) return 0;
int[][] dp = new int[n][n];
for(int len = 0; len < n; len++) {
for(int i = 0; i < n - len; i++) {
int j = i + len;
for(int k = i; k <= j; k++) {
int l = i > 0 ? nums[i-1] : 1;
int r = j < n-1 ? nums[j+1] : 1;
int left = k - 1 >= i ? dp[i][k-1] : 0;
int right = k + 1 <= j ? dp[k+1][j] : 0;
dp[i][j] = Math.max(dp[i][j], l*nums[k]*r + left + right);
}
}
}
return dp[0][n-1];
}
}
还有一种考虑subproblem的方式:dp[i][j]: : max coins I can get if there are balloons (i, j) left
,就是说i和j不算在内。那么dp方程现在变成:dp[i][j] = max(nums[i]*nums[k]*nums[j], dp[i][k] + dp[k][j])
,并且k取不到边界i或者j。这时候,base case结果就变了: dp[i][i] = 0, dp[i][i+1] = 0
参考discussion:
https://discuss.leetcode.com/...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。