312. Burst Balloons 戳气球
Title
有 n 個氣球,編號為0 到 n-1,每個氣球上都標(biāo)有一個數(shù)字,這些數(shù)字存在數(shù)組 nums 中。
現(xiàn)在要求你戳破所有的氣球。如果你戳破氣球 i ,就可以獲得 nums[left] * nums[i] * nums[right] 個硬幣。 這里的 left 和 right 代表和 i 相鄰的兩個氣球的序號。注意當(dāng)你戳破了氣球 i 后,氣球 left 和氣球 right 就變成了相鄰的氣球。
求所能獲得硬幣的最大數(shù)量。
說明:
- 你可以假設(shè) nums[-1] = nums[n] = 1,但注意它們不是真實(shí)存在的所以并不能被戳破。
- 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動態(tài)規(guī)劃
為了方便處理,我們對 nums 數(shù)組稍作處理,將其兩邊各加上題目中假設(shè)存在的 nums[?1] 和 nums[n] ,并保存在 val 數(shù)組中,即 val[i]=nums[i?1] 。之所以這樣處理是為了處理 nums[?1] ,防止下標(biāo)越界。
逆向思維,戳氣球會導(dǎo)致兩個氣球從不相鄰變成相鄰,很難處理,我們倒過來看,將全過程看作是每次添加一個氣球。
令 dp[i][j] 表示填滿開區(qū)間 (i,j) 能得到的最多硬幣數(shù),那么邊界條件是 i≥j?1,此時有 dp[i][j]=0。
可以寫出狀態(tài)轉(zhuǎn)移方程:
dp[i][j]={maxk=i+1j?1val[i]×val[k]×val[j]+dp[i][k]+dp[k][j],i<j?10,i>=j?1dp[i][j]=\begin{cases} max^{j-1}_{k=i+1}val[i]×val[k]×val[j]+dp[i][k]+dp[k][j],\quad i<j-1 \\\\ 0,\quad i>=j-1 \end{cases}dp[i][j]=??????maxk=i+1j?1?val[i]×val[k]×val[j]+dp[i][k]+dp[k][j],i<j?10,i>=j?1?
最終答案即為 dp[0][n+1]。實(shí)現(xiàn)時要注意到動態(tài)規(guī)劃的次序。
Code
def maxCoins(self, nums: List[int]) -> int:length, val = len(nums), [1] + nums + [1]dp = [[0] * (length + 2) for _ in range(length + 2)]for i in range(length - 1, -1, -1):for j in range(i + 2, length + 2):for k in range(i + 1, j):total = val[i] * val[k] * val[j]total += dp[i][k] + dp[k][j]dp[i][j] = max(dp[i][j], total)return dp[0][length + 1]復(fù)雜度分析
時間復(fù)雜度:O(n3),其中 n 是氣球數(shù)量。狀態(tài)數(shù)為 n2,狀態(tài)轉(zhuǎn)移復(fù)雜度為 O(n),最終復(fù)雜度為 O(n2×n)=O(n3)。
空間復(fù)雜度:O(n2),其中 n 是氣球數(shù)量。
總結(jié)
以上是生活随笔為你收集整理的312. Burst Balloons 戳气球的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 6.Vue Class 与 Style
- 下一篇: 编写你的第一个 Django 应用,第