Submission
Status:
xxxxxxxxxx
Subtask/Task Score:
0/100
Score: 0
User: NJTYTYTY
Problemset: ประลอง
Language: cpp
Time: 0.002 second
Submitted On: 2026-08-11 19:51:22
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <bitset>
using namespace std;
// กำหนด MAX_SUM ให้ครอบคลุมผลรวมสูงสุดที่เป็นไปได้
const int MAX_SUM = 200000;
// dp[i][c] เก็บ bitset ผลรวมที่เป็นไปได้เมื่อพิจารณาถึงยูนิตที่ i และเลือกมา c ตัว
// ประกาศเป็น Global Array เพื่อป้องกัน Stack Overflow และใช้ความเร็วสูงสุด
bitset<MAX_SUM + 1> dp[101][51];
int main() {
// เพิ่มความเร็วการอ่าน/เขียนข้อมูล
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
if (!(cin >> n)) return 0;
vector<int> a(n);
int min_val = 0;
int total_orig_sum = 0;
for (int i = 0; i < n; i++) {
cin >> a[i];
if (a[i] < min_val) min_val = a[i];
total_orig_sum += a[i];
}
// 1. Shift Offset เปลี่ยนค่าติดลบให้ไม่เป็นลบ
int C = -min_val;
vector<int> a_shift(n);
int sum_shift = 0;
for (int i = 0; i < n; i++) {
a_shift[i] = a[i] + C;
sum_shift += a_shift[i];
}
int k = n / 2;
// Base case: 0 ยูนิต ผลรวมเป็น 0
dp[0][0][0] = 1;
// 2. Dynamic Programming ด้วย Bitwise Operations
for (int i = 1; i <= n; i++) {
int val = a_shift[i - 1];
for (int c = 0; c <= k; c++) {
// ไม่เลือกยูนิตที่ i-1
dp[i][c] = dp[i - 1][c];
// เลือกยูนิตที่ i-1 (ขยับบิตไปทางซ้ายเท่ากับขนาด val)
if (c > 0) {
dp[i][c] |= (dp[i - 1][c - 1] << val);
}
}
}
// 3. ค้นหาผลรวมของฝ่ายที่ 1 ที่ทำให้ผลต่างสองฝ่ายน้อยที่สุด
int best_s = -1;
int min_diff = 1e9;
for (int s = 0; s <= sum_shift; s++) {
if (dp[n][k][s]) {
int orig_s1 = s - k * C;
int orig_s2 = total_orig_sum - orig_s1;
int diff = abs(orig_s1 - orig_s2);
if (diff < min_diff) {
min_diff = diff;
best_s = s;
}
}
}
// 4. Backtrack เพื่อย้อนหาตัวเลขของแต่ละฝ่าย
vector<int> team1, team2;
int curr_c = k;
int curr_s = best_s;
for (int i = n; i >= 1; i--) {
int val = a_shift[i - 1];
bool chosen_for_team1 = false;
if (curr_c > 0 && curr_s >= val && dp[i - 1][curr_c - 1][curr_s - val]) {
chosen_for_team1 = true;
}
if (chosen_for_team1) {
team1.push_back(a[i - 1]);
curr_c--;
curr_s -= val;
} else {
team2.push_back(a[i - 1]);
}
}
reverse(team1.begin(), team1.end());
reverse(team2.begin(), team2.end());
// 5. แสดงผลลัพธ์
for (int i = 0; i < (int)team1.size(); i++) {
cout << team1[i] << (i == (int)team1.size() - 1 ? "" : " ");
}
cout << "\n";
for (int i = 0; i < (int)team2.size(); i++) {
cout << team2[i] << (i == (int)team2.size() - 1 ? "" : " ");
}
cout << "\n";
return 0;
}