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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Leedcode][JAVA][按摩师][动态规划]

發布時間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Leedcode][JAVA][按摩师][动态规划] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【問題描述】

一個有名的按摩師會收到源源不斷的預約請求,每個預約都可以選擇接或不接。在每次預約服務之間要有休息時間,因此她不能接受相鄰的預約。給定一個預約請求序列,替按摩師找到最優的預約集合(總預約時間最長),返回總的分鐘數。注意:本題相對原題稍作改動示例 1:輸入: [1,2,3,1] 輸出: 4 解釋: 選擇 1 號預約和 3 號預約,總時長 = 1 + 3 = 4。 示例 2:輸入: [2,7,9,3,1] 輸出: 12 解釋: 選擇 1 號預約、 3 號預約和 5 號預約,總時長 = 2 + 9 + 1 = 12。 示例 3:輸入: [2,1,4,5,3,1,1,3] 輸出: 12 解釋: 選擇 1 號預約、 3 號預約、 5 號預約和 8 號預約,總時長 = 2 + 4 + 3 + 3 = 12。

【解答思路】

1. 動態規劃 二維狀態變量 由前往后 想清楚每一步

時間復雜度:O(N) 空間復雜度:O(N)

  • 設計狀態
    • dp[i][0] 表示:區間 [0,i] 里接受預約請求,并且下標為 i 的這一天不接受預約的最大時長;
    • dp[i][1] 表示:區間 [0,i] 里接受預約請求,并且下標為 i 的這一天接受預約的最大時長。
  • 狀態轉移方程
    • 今天不接受預約:或者是昨天不接受預約,或者是昨天接受了預約,取二者最大值,即:dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);
    • 今天接受預約:只需要從昨天不接受預約轉移而來,加上今天的時常,即:dp[i][1] = dp[i - 1][0] + nums[i]。

    3.初始化
    dp[0][0] = 0 與 dp[0][1] = nums[0];

    public int massage(int[] nums) {int len = nums.length;if (len == 0) {return 0;}if (len == 1) {return nums[0];}// dp[i][0]:區間 [0, i] 里接受預約請求,并且下標為 i 的這一天不接受預約的最大時長// dp[i][1]:區間 [0, i] 里接受預約請求,并且下標為 i 的這一天接受預約的最大時長int[][] dp = new int[len][2];dp[0][0] = 0;dp[0][1] = nums[0];for (int i = 1; i < len; i++) {dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1]);dp[i][1] = dp[i - 1][0] + nums[i];}return Math.max(dp[len - 1][0], dp[len - 1][1]);}

    優化:狀態數組多設置一行,以避免對極端用例進行討論

    public class Solution {public int massage(int[] nums) {int len = nums.length;// dp 數組多設置一行,相應地定義就要改變,遍歷的一些細節也要相應改變// dp[i][0]:區間 [0, i) 里接受預約請求,并且下標為 i 的這一天不接受預約的最大時長// dp[i][1]:區間 [0, i) 里接受預約請求,并且下標為 i 的這一天接受預約的最大時長int[][] dp = new int[len + 1][2];// 注意:外層循環從 1 到 =len,相對 dp 數組而言,引用到 nums 數組的時候就要 -1for (int i = 1; i <= len; i++) {dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1]);dp[i][1] = dp[i - 1][0] + nums[i - 1];}return Math.max(dp[len][0], dp[len][1]);} }

    優化 [滾動數組] 三個變量 時間復雜度:O(N) 空間復雜度:O(1)

    public class Solution {public int massage(int[] nums) {int len = nums.length;if (len == 0) {return 0;}if (len == 1) {return nums[0];}// dp[i & 1][0]:區間 [0, i] 里接受預約請求,并且下標為 i 的這一天不接受預約的最大時長// dp[i & 1][1]:區間 [0, i] 里接受預約請求,并且下標為 i 的這一天接受預約的最大時長int[][] dp = new int[2][2];dp[0][0] = 0;dp[0][1] = nums[0];for (int i = 1; i < len; i++) {dp[i & 1][0] = Math.max(dp[(i - 1) & 1][0], dp[(i - 1) & 1][1]);dp[i & 1][1] = dp[(i - 1) & 1][0] + nums[i];}return Math.max(dp[(len - 1) & 1][0], dp[(len - 1) & 1][1]);} }

    ?###### 2. 動態規劃 一維狀態變量 由前往后 想清楚每一步
    時間復雜度:O(N) 空間復雜度:O(N)

    public int massage(int[] nums) {int len = nums.length;if (len == 0) {return 0;}if (len == 1) {return nums[0];}// dp[i]:區間 [0, i] 里接受預約請求的最大時長int[] dp = new int[len];//初始化狀態dp[0] = nums[0];dp[1] = Math.max(nums[0], nums[1]);for (int i = 2; i < len; i++) {// 今天在選與不選中,選擇一個最優的dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);}return dp[len - 1];}

    優化 [滾動數組] 三個變量 時間復雜度:O(N) 空間復雜度:O(1)

    class Solution {public int massage(int[] nums) {int len = nums.length;if (len == 0) {return 0;}if (len == 1) {return nums[0];}// dp[i % 3]:區間 [0,i] 里接受預約請求的最大時長int[] dp = new int[3];dp[0] = nums[0];dp[1] = Math.max(nums[0], nums[1]);for (int i = 2; i < len; i++) {// 今天在選與不選中,選擇一個最優的dp[i % 3] = Math.max(dp[(i - 1) % 3], dp[(i - 2) % 3] + nums[i]);}return dp[(len - 1) % 3];} }

    【總結】

    1.動態規劃流程

    • 第 1 步:設計狀態
    • 第 2 步:狀態轉移方程
    • 第 3 步:考慮初始化
    • 第 4 步:考慮輸出
    • 第 5 步:考慮是否可以狀態壓縮

    2.動態規劃 自底向上 狀態轉移
    [一般編程] 自頂向下
    [記憶化遞歸」隨時可能面對新問題

    參考鏈接:https://leetcode-cn.com/problems/the-masseuse-lcci/solution/dong-tai-gui-hua-by-liweiwei1419-8/

    總結

    以上是生活随笔為你收集整理的[Leedcode][JAVA][按摩师][动态规划]的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。