打家劫舍(你是一個專業的小偷,計划偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。)


示例 1:

  輸入: [1,2,3,1]
  輸出: 4
解釋: 偷竊 1 號房屋 (金額 = 1) ,然后偷竊 3 號房屋 (金額 = 3)。
偷竊到的最高金額 = 1 + 3 = 4 。


示例 2:
  輸入: [2,7,9,3,1]
  輸出: 12
解釋: 偷竊 1 號房屋 (金額 = 2), 偷竊 3 號房屋 (金額 = 9),接着偷竊 5 號房屋 (金額 = 1)
偷竊到的最高金額 = 1 + 3 = 4

通過

/** * * @param arr * @return * 運用動態規划解決該題:假設我們數組arr為{2,7,9,3,1},opt(i)表示當前利益最大化,我們從opt(4) * 開始,opt(4):盜賊要么盜取下標為4的房間,要么不盜取,盜取下標為4的房間, * 則opt(4) = opt(2) + arr[4],不盜取opt(4) = opt(3)則opt(4)在兩者之間選最大值, * 即opt(4) = Math.max(opt(3),opt(2)+arr[4]) * 返回判斷條件:(1)數組長度等於0,return 0; * (2)數組長度等於1,return arr[0]; * (3)因為opt(2) = Math.max(opt(1),opt(0)+arr[2]),所以數組長度 * 等於2的話,return Math.max(arr[0],arr[1]); * */

根據上述分析,我們給出遞歸方法和非遞歸方法

    //遞歸方法 
   public static int rob(int[] arr) { return rec_opt(arr,arr.length - 1); } 
    public static int rec_opt(int[] arr,int i) { if(arr.length == 0) return 0; if(i == 0) return arr[i]; else if(i == 1) return Math.max(arr[i-1], arr[i]); else { int A = rec_opt(arr,i - 2) + arr[i]; int B = rec_opt(arr,i - 1); return Math.max(A, B); } }
//非遞歸方法
    public static int dp_opt(int[] arr) { if(arr.length == 0) { return 0; } if(arr.length == 1) { return arr[0]; } if(arr.length == 2) { return Math.max(arr[0], arr[1]); } int[] opt = new int[arr.length]; opt[0] = arr[0]; opt[1] = Math.max(arr[1],arr[0]); for(int i = 2;i<opt.length;i++) { int A = opt[i - 2] + arr[i]; int B = opt[i - 1]; opt[i] = Math.max(A, B); } return opt[opt.length - 1]; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM