สมมุติว่าเรามีอาร์เรย์ A หนึ่งอัน เราต้องย้ายทุกองค์ประกอบของ A ไปที่รายการ B หรือรายการ C (รายการ B และ C เหล่านี้ว่างในตอนแรก) เราต้องตรวจสอบว่าหลังจากการย้ายดังกล่าว เป็นไปได้ว่าค่าเฉลี่ย ของ B เท่ากับค่าเฉลี่ยของ C และ B และ C ไม่เว้นว่างทั้งคู่
ดังนั้นหากอินพุตเป็น − [1,2,3,4,5,6,7,8,9,10] ผลลัพธ์จะเป็นจริง
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
- n :=ขนาด A รวม :=0
- สำหรับการเริ่มต้น i :=0 เมื่อฉัน
- รวม :=รวม + A[i]
- ถ้าทั้งหมด * i mod n เท่ากับ 0 แล้ว −
- เป็นไปได้ :=จริง
- คืนค่าเท็จ
- สำหรับการเริ่มต้น l :=1 เมื่อ l <=(n / 2) อัปเดต (เพิ่ม l ขึ้น 1) ทำ −
- dp[j, l] :=dp[j, l] หรือ dp[j - x, l - 1]
- ถ้า (ผลรวม * i) mod n เท่ากับ 0 และ dp[total * i / n, i] ไม่ใช่ศูนย์ ดังนั้น −
- คืนค่าจริง
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#include <bits/stdc++.h> using namespace std; class Solution { public: bool splitArraySameAverage(vector<int>& A) { int n = A.size(); int total = 0 ; for(int i = 0; i < n; i++) total += A[i]; bool isPossible = false; int m = n / 2; for (int i = 1; i <= m && !isPossible; ++i) if (total*i%n == 0) isPossible = true; if (!isPossible) return false; vector < vector <bool> > dp(total + 1, vector <bool>((n / 2) + 1)); dp[0][0] = true; for(int i = 0; i < n; i++){ int x = A[i]; for(int j = total; j >= x; j--){ for(int l = 1; l <= (n / 2); l++){ dp[j][l] = dp[j][l] || dp[j - x][l - 1]; } } } for(int i = 1 ; i <= (n / 2); i++){ if((total * i) % n == 0 && dp[total * i / n][i]) return true; } return false; } }; main(){ Solution ob; vector<int> v = {1,2,3,4,5,6,7,8,9,10}; cout << (ob.splitArraySameAverage(v)); }
อินพุต
{1,2,3,4,5,6,7,8,9,10}
ผลลัพธ์
1