พิจารณาว่าคุณเป็นโจรมืออาชีพ และคุณกำลังวางแผนที่จะปล้นบ้านตามถนน แต่ละบ้านมีเงินเก็บอยู่จำนวนหนึ่ง บ้านทุกหลังจัดเป็นวงกลม นั่นหมายถึงบ้านหลังแรกเป็นเพื่อนบ้านของบ้านหลังสุดท้าย เราต้องจำไว้ว่าบ้านที่อยู่ติดกันมีระบบรักษาความปลอดภัยเชื่อมต่อและจะติดต่อตำรวจโดยอัตโนมัติหากบ้านสองหลังถูกบุกรุกในคืนเดียวกัน ดังนั้นหากเรามีรายการจำนวนเต็มที่แสดงถึงจำนวนเงินของแต่ละบ้าน ให้กำหนดจำนวนเงินสูงสุดที่คุณสามารถปล้นได้ในคืนเดียวโดยไม่ต้องแจ้งตำรวจ ดังนั้นหากอาร์เรย์คือ [1,2,3,1] ผลลัพธ์จะเป็น 4
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
- เรากำลังใช้โมดูลหนึ่งที่เรียกว่า Solve() ซึ่งจะรับอาร์เรย์ จุดเริ่มต้นและจุดสิ้นสุด ซึ่งจะทำหน้าที่ด้านล่าง −
- ans :=nums[start]
- สร้างหนึ่งตารางสำหรับโปรแกรมไดนามิก ชื่อ dp และขนาดเท่ากับขนาด nums
- dp[start] :=nums[start]
- for i :=start + 1 to end
- สุดท้าย :=dp[i – 1]
- lastToLast :=0 เมื่อ i – 2 มิฉะนั้น dp[i – 2]
- dp[i] :=สูงสุดของ nums[i] + lastToLast และล่าสุด
- ans :=สูงสุดของ dp[i] และ ans
- คืนสินค้า
- การปล้นทำได้ดังนี้ -
- n :=ขนาดของ nums
- ถ้า n เป็นศูนย์ ให้คืนค่า 0
- ถ้า n =1 ให้คืนค่า nums[0]
- คืนค่าสูงสุดของการแก้(nums, 0, n - 2), แก้(nums, 1, n – 1)
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int solve(vector <int>& nums, int start, int end){
int ans = nums[start];
vector <int> dp(nums.size());
dp[start] = nums[start];
for(int i = start + 1; i <= end; i++){
int last = dp[i - 1];
int lastToLast = i - 2 < start? 0 : dp[i - 2];
dp[i] = max(nums[i] + lastToLast, last);
ans = max(dp[i], ans);
}
return ans;
}
int rob(vector<int>& nums) {
int n = nums.size();
if(!n)return 0;
if(n == 1)return nums[0];
return max(solve(nums, 0, n - 2), solve(nums, 1, n - 1));
}
};
main(){
vector<int> v = {1,2,3,5};
Solution ob;
cout << ob.rob(v);
} อินพุต
[1,2,3,5]
ผลลัพธ์
7