整数集合的划分:
给定一个包含 N N N 个正整数的集合,请你将它划分为两个集合 A 1 A_1 A1 和 A 2 A_2 A2,其中 A 1 A_1 A1 包含 n 1 n_1 n1 个元素, A 2 A_2 A2 包含 n 2 n_2 n2 个元素。
集合中可以包含相同元素。
用 S 1 S_1 S1 表示集合 A 1 A_1 A1 内所有元素之和, S 2 S_2 S2 表示集合 A 2 A_2 A2 内所有元素之和。
请你妥善划分,使得 ∣ n 1 − n 2 ∣ |n_1−n_2| ∣n1−n2∣ 尽可能小,并在此基础上 ∣ S 1 − S 2 ∣ |S_1−S_2| ∣S1−S2∣ 尽可能大。
输入格式
第一行包含整数 N N N。
第二行包含 N N N 个正整数。
输出格式
再一行中输出 ∣ n 1 − n 2 ∣ |n_1−n_2| ∣n1−n2∣ 和 ∣ S 1 − S 2 ∣ |S_1−S_2| ∣S1−S2∣,两数之间空格隔开。
数据范围
2 ≤ N ≤ 1 0 5 , 2≤N≤10^5, 2≤N≤105,
保证集合中各元素以及所有元素之和小于 2 31 2^{31} 231。
输入样例1:
10
23 8 10 99 46 2333 46 1 666 555
输出样例1:

0 3611
输入样例2:
13
110 79 218 69 3721 100 29 135 2 6 13 5188 85
输出样例2:
1 9359
分析: 贪心问题。首先题目条件是首先要保证 n 1 − n 2 n_1-n_2 n1−n2最小,故而要分奇偶, n n n为偶数时 n 1 − n 2 = 0 n_1-n_2=0 n1−n2=0, n n n为奇数时 n 1 − n 2 = 1 n_1-n_2=1 n1−n2=1。所以就是将集合对半分,找出差距最大的集合。可以排序,然后分成两部分相减就是答案了。
证明:设两个集合 S 1 = { a 1 , a 2 . . . a n 2 } , S 2 = { a n 2 + 1 . . . a n } S_1=\left \{ a_1,a_2...a_{\frac{n}{2}}\right \} ,S_2=\left \{ a_{\frac{n}{2}+1}...a_n\right \} S1={
a1,a2...a2n},S2={
a2n+1...an},假设 S 1 ≤ S 2 S_1 \le S_2 S1≤S2,如果 ∃ a x ∈ S 1 , a y ∈ S 2 \exist a_x\in S_1,a_{y} \in S_2 ∃ax∈S1,ay∈S2使得 a x > a y a_x>a_y ax>ay,那么如果将 a x a_x ax分给 S 2 S_2 S2, a y a_y ay分给 S 1 S_1 S1,此时两个集合的大小为 S 1 ′ = S 1 − ( a x − a y ) , S 2 ′ = S 2 + ( a x − a y ) , S_1'=S_1-(a_x-a_y),S_2'=S_2+(a_x-a_y), S1′=S1−(ax−ay),S2′=S2+(ax−ay),则 S 2 ′ − S 1 ′ = S 2 − S 1 + 2 ( a x − a y ) > S 2 − S 1 , S_2'-S_1'=S_2-S_1+2(a_x-a_y)>S_2-S_1, S2′−S1′=S2−S1+2(ax−ay)>S2−S1,与最优解矛盾。所以 S 1 ≤ S 2 S_1 \le S_2 S1≤S2恒成立。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int a[N];
int main(){
int n,res=0,sum=0;
cin>>n;
for(int i=0;i<n;i++) cin>>a[i],sum+=a[i];
sort(a,a+n);
for(int i=0;i<n/2;i++) res+=a[i];
cout<<n%2<<" "<<sum-2*res<<endl;
}