【LeetCode & 劍指offer刷題】動態規劃與貪婪法題14:Burst Balloons
阿新 • • 發佈:2019-01-06
【LeetCode & 劍指offer 刷題筆記】目錄(持續更新中...)
Burst Balloons
Given n balloons, indexed from 0 to n-1 . Each balloon is painted with a number on it represented by array nums-
You may imagine nums[-1] = nums[n] = 1
.
- 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100
C++ /* 問題:打氣球遊戲 方法:動態規劃 dp[i][j]表示打爆區間[i,j]中的所有氣球能得到的最多金幣 dp[i][j] = max(dp[i][j], nums[i - 1]*nums[k]*nums[j + 1] + dp[i][k - 1] + dp[k + 1][j]) , i ≤ k ≤ j 遍歷區間, 遍歷氣球,在 區間[i,j]中k氣球最後打爆的情況,使最後能得到最多金幣 我們其實只是更新了 dp 陣列的右上三角區域,我們最終要返回的值存在 dp[1][n] 中,其中 n 是兩端新增 1 之前陣列 nums 的個數 例: [3, 1, 5, 8],得到的dp陣列如下: 0 0 0 0 0 0 0 3 30 159 167 0 0 0 15 135 159 0 0 0 0 40 48 0 0 0 0 0 40 0 0 0 0 0 0 0 */ class Solution { public : int maxCoins ( vector < int >& nums ) { if ( nums . empty ()) return 0 ; int n = nums . size (); nums . insert ( nums . begin (), 1 ); // 首部填充 0 nums . push_back ( 1 ); // 尾部填充 0,首尾填充後,原nums中數的索引區間為[1,n] vector < vector < int >> dp ( n + 2 , vector < int >( n + 2 )); // 構建 dp 陣列 for ( int len = 1 ; len <= n ; len ++) // 區間長度(先算小區間,再算大區間,從小問題算到大問題) { for ( int left = 1 ; left <= n - len + 1 ; left ++) // 左端點座標 ,left =1~ { int right = left + len - 1 ; // 右端點座標 ,right = len~n (在[1,n]範圍left和right構成滑動窗) for ( int k = left ; k <= right ; k ++) // 打爆的氣球位置 , k = left~right { dp[left][right] = max(dp[left][right], nums[left-1]*nums[k]*nums[right+1] + dp[left][k-1] + dp[k+1][right]); // 後面一項表示 [left, right] 區間中 ,k氣球最後打爆的情況,故最後需要加上nums[left-1]*nums[k]*nums[right+1]項 } } } return dp [ 1 ][ n ]; //dp[1][n]與 nums[0]和nums[n+1]關聯,[1,n]區間對應原陣列區間的數 } };