#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
int n,a[201],sum,ans=1000000000,ans1,ans2,f[201][805];
bool p[201][805];
inline int mx(int x,int y) {
if(abs(x) < abs(y)) return x;
return y;
}
inline bool mx1(int x,int y) {
if(abs(x) < abs(y)) return 1;
return 0;
}
inline bool cmp(int x,int y) {
return x > y;
}
int main() {
memset(f,0x3f3f3f,sizeof(f));
scanf("%d",&n);
for(int i = 1;i <= n; i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1,cmp);
f[1][201] = a[1];
p[1][201] = 0;
f[1][199] = 0 - a[1];
p[1][199] = 1;
for(int i = 2;i <= n; i++)
for(int j = 200 - i - 1;j <= 200 + i + 1; j++) {
f[i][j] = mx(f[i-1][j+1] - a[i],f[i-1][j-1] + a[i]);
p[i][j] = mx1(f[i-1][j+1] - a[i],f[i-1][j-1] + a[i]);
// printf("%d %d %d %d\n",i,j,f[i][j],p[i][j]);
}
for(int i = 199;i <= 201; i++) {
if(abs(f[n][i]) < ans) {
sum = i;
ans = abs(f[n][i]);
}
}
for(int i = n;i >= 1; i--) {
if(!p[i][sum]) ans1 += a[i],sum -= 1;
else ans2 += a[i],sum += 1;
// printf("%d %d\n",i,sum);
}
printf("%d %d",min(ans1,ans2),max(ans1,ans2));
return 0;
}
f[i][j]表示到第i位时a1与a2元素个数差为j(以200为基数,防止出现负数下标)时的最小差值的绝对值(a1和a2为实时更新的两部分兵)
p[i][j]记录答案路径,求最后答案
求代码错误或一组可调试的hack数据,谢谢