一、題目大意
標簽: 分治
https://leetcode.cn/problems/burst-balloons
有 n 個氣球,編號為0 到 n - 1,每個氣球上都標有一個數字,這些數字存在陣列 nums 中,
現在要求你戳破所有的氣球,戳破第 i 個氣球,你可以獲得 nums[i - 1] * nums[i] * nums[i + 1] 枚硬幣, 這里的 i - 1 和 i + 1 代表和 i 相鄰的兩個氣球的序號,如果 i - 1或 i + 1 超出了陣列的邊界,那么就當它是一個數字為 1 的氣球,
求所能獲得硬幣的最大數量,
示例 1:
輸入:nums = [3,1,5,8]
輸出:167
解釋:
nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
coins = 315 + 358 + 138 + 181 = 167
示例 2:
輸入:nums = [1,5]
輸出:10
提示:
- n == nums.length
- 1 <= n <= 300
- 0 <= nums[i] <= 100
二、解題思路
分治+動態規劃,dp[i][j] = maxCoins(nums[i]~nums[j]) 表示從第i個氣球到第j個氣球的最大值,我們所求答案就是ans = dp[1][n],i與j之間找一個氣球k,i到k-1之間最大分數,k+1與j之間最大值,最后打破氣球k,所以動態轉移方程為:dp[i][j] = max(c[i][k-1] + nums[k-1]nums[k]nums[k+1]+c[k+1][j]),
三、解題方法
3.1 Java實作
public class Solution {
public int maxCoins(int[] nums) {
int n = nums.length;
int[] nums2 = new int[n + 2];
nums2[0] = 1;
nums2[n + 1] = 1;
for (int i = 0; i < n; i++) {
nums2[i + 1] = nums[i];
}
int[][] dp = new int[n + 2][n + 2];
for (int l = 1; l <= n; l++) {
for (int i = 1; i <= n - l + 1; i++) {
int j = i + l - 1;
for (int k = i; k <= j; k++) {
dp[i][j] = Math.max(dp[i][j], dp[i][k - 1] + nums2[i - 1] * nums2[k] * nums2[j + 1] + dp[k + 1][j]);
}
}
}
return dp[1][n];
}
}
四、總結小記
- 2022/7/10 兩地奔波的一天
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/498637.html
標籤:其他
