日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[Leetcode][第312题][JAVA][戳气球][动态规划][记忆化搜索]

發(fā)布時(shí)間:2023/12/10 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Leetcode][第312题][JAVA][戳气球][动态规划][记忆化搜索] 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

【問題描述】[困難]

【解答思路】

1. 記憶化搜索



時(shí)間復(fù)雜度:O(n^3) 空間復(fù)雜度:O(n^2)

class Solution {public int[][] rec;public int[] val;public int maxCoins(int[] nums) {int n = nums.length;val = new int[n + 2];for (int i = 1; i <= n; i++) {val[i] = nums[i - 1];}val[0] = val[n + 1] = 1;rec = new int[n + 2][n + 2];for (int i = 0; i <= n + 1; i++) {Arrays.fill(rec[i], -1);}return solve(0, n + 1);}public int solve(int left, int right) {if (left >= right - 1) {return 0;}if (rec[left][right] != -1) {return rec[left][right];}for (int i = left + 1; i < right; i++) {int sum = val[left] * val[i] * val[right];sum += solve(left, i) + solve(i, right);rec[left][right] = Math.max(rec[left][right], sum);}return rec[left][right];} }
2. 動(dòng)態(tài)規(guī)劃

第 1 步:設(shè)計(jì)狀態(tài)
dp[i][j] = x 表示,戳破氣球 i 和氣球 j 之間(開區(qū)間,不包括 i 和 j)的所有氣球,可以獲得的最高分?jǐn)?shù)為 x。

第 2 步:狀態(tài)轉(zhuǎn)移方程

i>j之間沒有氣球 均為0
第 3 步:考慮初始化

base case 已經(jīng)都被初始化為 0
int[][] dp = new int[n + 2][n + 2];

第 4 步:考慮輸出
dp[0][n+1] )


斜著遍歷較難實(shí)現(xiàn),一般從上到下實(shí)現(xiàn)

時(shí)間復(fù)雜度:O(N^3) 空間復(fù)雜度:O(N^2)

class Solution {public int maxCoins(int[] nums) {int n = nums.length;int[][] rec = new int[n + 2][n + 2];int[] val = new int[n + 2];val[0] = val[n + 1] = 1;for (int i = 1; i <= n; i++) {val[i] = nums[i - 1];}for (int i = n - 1; i >= 0; i--) {for (int j = i + 2; j <= n + 1; j++) {for (int k = i + 1; k < j; k++) {int sum = val[i] * val[k] * val[j];sum += rec[i][k] + rec[k][j];rec[i][j] = Math.max(rec[i][j], sum);}}}return rec[0][n + 1];} }

【總結(jié)】

1. 動(dòng)態(tài)規(guī)劃流程

第 1 步:設(shè)計(jì)狀態(tài)
第 2 步:狀態(tài)轉(zhuǎn)移方程
第 3 步:考慮初始化
第 4 步:考慮輸出
第 5 步:考慮是否可以狀態(tài)壓縮

2.關(guān)于「狀態(tài)」的窮舉,最重要的一點(diǎn)就是:狀態(tài)轉(zhuǎn)移所依賴的狀態(tài)必須被提前計(jì)算出來(lái)。 通過 初始狀態(tài)的base case 和最終狀態(tài) 推導(dǎo)出 i,j 的遍歷方向,保證正確的狀態(tài)轉(zhuǎn)移
3.關(guān)鍵在于 dp 數(shù)組的定義,需要避免子問題互相影響,所以我們反向思考,將 dp[i][j] 的定義設(shè)為開區(qū)間,考慮最后戳破的氣球是哪一個(gè),以此構(gòu)建了狀態(tài)轉(zhuǎn)移方程。
4. 回溯算法偽代碼以及套路

回溯算法超時(shí) 需要結(jié)合記憶化搜索

int res = Integer.MIN_VALUE; /* 輸入一組氣球,返回戳破它們獲得的最大分?jǐn)?shù) */ int maxCoins(int[] nums) {backtrack(nums, 0); return res; } /* 回溯算法的偽碼解法 */ void backtrack(int[] nums, int socre) {if (nums 為空) {res = max(res, score);return;}for (int i = 0; i < nums.length; i++) {int point = nums[i-1] * nums[i] * nums[i+1];int temp = nums[i];// 做選擇在 nums 中刪除元素 nums[i]// 遞歸回溯backtrack(nums, score + point);// 撤銷選擇將 temp 還原到 nums[i]} } 根據(jù)題意定義出口(可選) for 選擇 in 選擇列表:# 做選擇將該選擇從選擇列表移除路徑.add(選擇)backtrack(路徑, 選擇列表)# 撤銷選擇路徑.remove(選擇)將該選擇再加入選擇列表 https://labuladong.gitbook.io/algo/di-ling-zhang-bi-du-xi-lie/hui-su-suan-fa-xiang-jie-xiu-ding-ban

參考鏈接:https://leetcode-cn.com/problems/burst-balloons/solution/dong-tai-gui-hua-tao-lu-jie-jue-chuo-qi-qiu-wen-ti/

轉(zhuǎn)載鏈接:https://leetcode-cn.com/problems/burst-balloons/solution/chuo-qi-qiu-by-leetcode-solution/

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的[Leetcode][第312题][JAVA][戳气球][动态规划][记忆化搜索]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。