很裸了
但是没打搜索 打了状压
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;
const int N=35;
int n,a[N];
ll s1[N][1<<16],s2[N][1<<16];
int main()
{
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
while (~scanf("%d",&n))
{
ll tot=0;
for (int i=1;i<=n;i++) scanf("%d",a+i),tot+=a[i];
int mid=n>>1;
for (int i=0;i<=n;i++) s1[i][0]=s2[i][0]=0;
for (int i=0;i<(1<<mid);i++)
{
ll sum=0,cnt=0;
for (int j=1;j<=mid;j++)
if (i>>(j-1)&1)
sum+=a[j],cnt++;
s1[cnt][++*s1[cnt]]=sum;
}
for (int i=0;i<=n;i++) sort(s1[i]+1,s1[i]+*s1[i]+1);
for (int i=0;i<(1<<(n-mid));i++)
{
ll sum=0,cnt=0;
for (int j=1;j<=n-mid;j++)
if (i>>(j-1)&1)
sum+=a[mid+j],cnt++;
s2[cnt][++*s2[cnt]]=sum;
}
for (int i=0;i<=n;i++) sort(s2[i]+1,s2[i]+*s2[i]+1);
ll ans=0,aim=tot/2;
for (int i=0;i<=mid;i++)
for (int j=mid-i;j<=mid-i+(n&1);j++)
{
int tot1=*s1[i],tot2=*s2[j];
int p2=tot2;
for (int k=1;k<=tot1;k++)
{
while (p2>1 && s1[i][k]+s2[j][p2]>aim) p2--;
if (s1[i][k]+s2[j][p2]>aim) break;
ans=max(ans,s1[i][k]+s2[j][p2]);
}
}
printf("%lld\n",tot-2*ans);
}
return 0;
}