leetcode 戳氣球
阿新 • • 發佈:2018-08-09
-- n-1 bsp 依賴關系 num length right 編號 最好
有 n
個氣球,編號為0
到 n-1
,每個氣球上都標有一個數字,這些數字存在數組 nums
中。
現在要求你戳破所有的氣球。每當你戳破一個氣球 i
時,你可以獲得 nums[left] * nums[i] * nums[right]
個硬幣。 這裏的 left
和 right
代表和 i
相鄰的兩個氣球的序號。註意當你戳破了氣球 i
後,氣球 left
和氣球 right
就變成了相鄰的氣球。
求所能獲得硬幣的最大數量。
說明:
- 你可以假設
nums[-1] = nums[n] = 1
,但註意它們不是真實存在的所以並不能被戳破。 - 0 ≤
n
≤ 500, 0 ≤nums[i]
≤ 100
示例:
輸入:[3,1,5,8]
輸出:167 解釋:
nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> [] coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167
class Solution { public int maxCoins(int[] nums) { int len = nums.length; int[] langarr = new int[len+2]; langarr[0] = 1;for (int i = 0, j = 1; i < len; i++, j++) langarr[j] = nums[i]; len = langarr.length; int[][] dp = new int[len][len]; langarr[len-1] = 1; for (int i = 2; i < len; i++) { for (int j = 0; j+i < len; j++) { for (int k = j+1; k < j+i; k++) { dp[j][j+i] = Math.max(dp[j][j+i], dp[j][k]+dp[k][j+i]+langarr[j]*langarr[k]*langarr[j+i]); } } } return dp[0][len-1]; } }
dp[i][j]的含義是 第i個氣球到第j個氣球(不包含i,j) ,最好的紮法能得多少分。
dp[j][j+i] = Math.max(dp[j][j+i], dp[j][k]+dp[k][j+i]+langarr[j]*langarr[k]*langarr[j+i]);
以上是最精華的遞推公式,這種屬於分治思想,分治的動態規劃題 dp為二維的時候,從短的長度到長的長度去滲透,
k的含義是,假設k是最後一個紮破的氣球, 這個想法最關鍵(自己想到了分治,但是總是感覺左右會有依賴沒法分),也是這道題最難想到的點,最後一個紮破的氣球的左邊和右邊是完全沒有依賴關系的,可以分別運算的部分。
如果k是最後一個紮破的,那麽最後一次的得分也可以得出。
leetcode 戳氣球