Submission
Status:
---PP-PPPP
Subtask/Task Score:
60/100
Score: 60
User: NJTYTYTY
Problemset: ประลอง
Language: cpp
Time: 0.002 second
Submitted On: 2026-08-11 19:48:18
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
int main() {
// เพิ่มความเร็วในการ Read/Write I/O
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 max_a_shift = 0;
for (int i = 0; i < n; i++) {
a_shift[i] = a[i] + C;
if (a_shift[i] > max_a_shift) {
max_a_shift = a_shift[i];
}
}
int k = n / 2; // จำนวนยูนิตของฝ่ายที่ 1
int max_sum = k * max_a_shift;
// 2. สร้างตาราง DP: dp[i][c][s]
// dp[i][c][s] = true หมายถึง ใช้ c ยูนิตจาก i ยูนิตแรก ได้ผลรวมเป็น s
vector<vector<vector<bool>>> dp(n + 1, vector<vector<bool>>(k + 1, vector<bool>(max_sum + 1, false)));
dp[0][0][0] = true;
for (int i = 1; i <= n; i++) {
int val = a_shift[i - 1];
for (int c = 0; c <= k; c++) {
for (int s = 0; s <= max_sum; s++) {
// กรณีไม่เลือกยูนิต i-1 เข้าฝ่ายที่ 1
if (dp[i - 1][c][s]) {
dp[i][c][s] = true;
}
// กรณีเลือกยูนิต i-1 เข้าฝ่ายที่ 1
if (c > 0 && s >= val && dp[i - 1][c - 1][s - val]) {
dp[i][c][s] = true;
}
}
}
}
// 3. หาผลรวม s_best ของฝ่ายที่ 1 ที่ทำให้ผลต่างผลรวมสองฝ่ายน้อยที่สุด
int best_s = -1;
int min_diff = 1e9;
for (int s = 0; s <= max_sum; 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;
}