Problem:
Problem 05: Split Up!

勇者ポン太とその親友同じく勇者ゴン太は、これから壮大な冒険へと出発するために、それぞれ仲間を求めてルイーダの酒場へやって来ました。酒場には、冒険に出たくてうずうずしている武闘家や僧侶、魔法使いがたくさん居ます。

心やさしいゴン太はポン太を気遣い、「先に仲間を選んでいいよ。」と言いました。

一方、ポン太もゴン太が心配でなりません。「いや、君が先に選んでいいよ。」と言い返しました。

お互い譲り合いが続き、ついにルイーダがこう提案しました。「じゃあ、ここにいる n 人の登録者をそれぞれのパーティの合計戦闘力がなるべく均等になるように、この"パーティ分けマシン"で分けてあげるわ。」

あなたに与えられた仕事は、パーティ分けマシンに組み込まれているプログラムを作成することです。

このプログラムは　n 個の整数を入力し、それらを２つのグループ A, B に分けたときの、A に含まれる整数の合計値と B に含まれる整数の合計値の差の最小値を出力しなければなりません。

このマシンのおかげで、ポン太とゴン太は仲良く仲間を見つけ、壮大な冒険へと出かけて行きました・・。

Input

入力として複数のデータセットが与えられます。各データセットは以下の形式で与えられます：

n (登録者の数： 整数)

a1 a2 ... an　（各登録者の戦闘力： 空白区切りの整数）

n は 20 以下であり、各登録者の戦闘力は 100 万を越えません。

n が 0 のとき入力の終わりとします。

Output

各データセットに対して、最小値を1行に出力して下さい。

Sample Input

5
1 2 3 4 5
4
2 3 5 7
0

Output for the Sample Input

1
1

Solution in C (judge verdict: Accepted)

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define REP(i,m,n) for(i=(m);i<((int)(n));i++)
#define rep(i,n) REP(i,0,n)
#define INFTY (1<<21)
#define LLINFTY (1LL<<53)
typedef long long ll;
typedef unsigned long long ull;
int n,a[20],res;
int s1[111111],s2[111111],s3[111111];
int ab(int n){return n<0?-n:n;}
inline int min(int a,int b)
{
  return a<b?a:b;
}
void solve()
{
  int x,y,c; x=y=c=0;
  int sp=0;
  s1[sp]=s2[sp]=s3[sp]=0; sp++;
  while(sp){
    sp--;
    x=s1[sp];
    y=s2[sp];
    c=s3[sp];
    if(c==n){
      res=min(res,ab(x-y));
      continue;
    }
    s1[sp]=x+a[c];
    s2[sp]=y;
    s3[sp]=c+1;
    sp++;
    s1[sp]=x;
    s2[sp]=y+a[c];
    s3[sp]=c+1;
    sp++;
  }
}
int main(void)
{
  int i;
  for(;;){
    scanf("%d",&n); if(!n)break;
    rep(i,n) scanf("%d",a+i);
    res=INFTY;
    solve();
    printf("%d\n",res);
  }
  return 0;
}