算法:DP
program P1114;
var
n:longint;
v,sum:array[0..101] of longint;{sum[i]表示前i块水晶的高度之和。}
f:array[0..101,0..8001] of longint;{用f[i,j]表示在前i块水晶里,高塔与矮塔的高度差为j的最矮的塔的高度,所以目标即f[n,0]。}
procedure init;
var
i:longint;
begin
read(n);
sum[0]:=0;
for i:=1 to n do read(v[i]);
end;
procedure main;
var
i,j,max,t:longint;
begin
fillchar(f,sizeof(f),200);{因为要求满足条件的最大值,所以初始化为最小值。}
{依旧是选择排序将水晶的高度按顺序排好。}
for i:=1 to n do
begin
for j:=i+1 to n do
begin
if v[i]>v[j] then
begin
t:=v[i];
v[i]:=v[j];
v[j]:=t;
end;
end;
end;
for i:=1 to n do sum[i]:=sum[i-1]+v[i];
f[1,v[1]]:=v[1];
for i:=2 to n do
begin
for j:=sum[i] downto 0 do{最大的高塔和矮塔的差是sum[i],最小的差就是0。}
begin
max:=f[i-1,j];{表示当前的水晶既不放在高塔上,也不放在矮塔上。}
if f[i-1,j+v[i]]>max then max:=f[i-1,j+v[i]];{表示放在高塔上,这时差距又加大了,而矮塔的高度没变。}
if j-v[i]>=0 then{如果放在矮塔上,就先要判断放在矮塔上以后矮塔是否会成为高塔。大于等于0即差距依然存在,不会成为高塔。}
begin
if f[i-1,j-v[i]]+v[i]>max then max:=f[i-1,j-v[i]]+v[i]{差距缩小同时矮塔的高度增加了。}
else if f[i-1,abs(j-v[i])]-abs(j-v[i])+v[i]>max then max:=f[i-1,abs(j-v[i])]-abs(j-v[i])+v[i];{否则,之前的高塔会变成矮塔。}
f[i,j]:=max;{在这些情况中取一个最大值。}
end;
end;
end;
if f[n,0]>0 then writeln(f[n,0]) else writeln('Impossible');{输出。}
end;
begin
assign(input,'P1114.in'); reset(input);
assign(output,'P1114.out'); rewrite(output);
init;
main;
close(input); close(output);
end.