สมมติว่าเรามีอาร์เรย์ที่ไม่ว่างซึ่งมีเฉพาะตัวเลขที่เป็นบวก เราต้องค้นหาว่าอาร์เรย์นั้นสามารถแบ่งออกเป็นสองชุดย่อยได้หรือไม่ เพื่อให้ผลรวมขององค์ประกอบในชุดย่อยทั้งสองเท่ากัน ดังนั้นหากอินพุตเป็น [1,5,11,5] เอาต์พุตจะเป็นจริง เนื่องจากอาร์เรย์นี้สามารถแบ่งพาร์ติชันเป็น [1, 5, 5] และ [11]
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
- n :=ขนาดของอาร์เรย์
- ผลรวม :=0
- สำหรับ i :=0 ถึง n – 1
- sum :=sum + nums[i]
- ถ้าผลรวมเป็นเลขคี่ ให้คืนค่าเท็จ
- sum :=sum / 2
- สร้างหนึ่งอาร์เรย์ที่เรียกว่า dp ของขนาดรวม + 1
- dp[0] :=จริง
- สำหรับ i ในช่วง 0 ถึง n – 1
- x :=nums[i]
- สำหรับ j :=รวมลงไป j – x
- dp[j] :=dp[j] หรือ dp[j - x] ซึ่งไม่ใช่ 0
- ส่งคืน dp[sum]
ตัวอย่าง(C++)
ให้เราดูการใช้งานต่อไปนี้เพื่อทำความเข้าใจ −
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
bool canPartition(vector<int>& nums) {
int n = nums.size();
int sum = 0;
for(int i =0;i<n;i++)sum+=nums[i];
if(sum&1)return false;
sum/=2;
vector <bool> dp(sum+1);
dp[0] = true;
for(int i =0;i<n;i++){
int x = nums[i];
for(int j =sum;j-x>=0;j--){
dp[j]=dp[j] || dp[j-x];
}
}
return dp[sum];
}
};
main(){
Solution ob;
vector<int> v = {1,5,11,5};
cout << ob.canPartition(v);
} อินพุต
[1,5,11,5]
ผลลัพธ์
1