将n个数分成两部分,使其个数之差不超过1,求和之差最小是多少?
n≤100,ai≤450
以个数和权值为费用作布尔背包即可。
#include<iostream>
using namespace std;
int f[3][51][45001];int a[101];
int main()
{ int n;
cin>>n;int s=0;
for (int i=1;i<=n;++i)
{ cin>>a[i];
s+=a[i];
}
for (int i=0;i<=1;++i)
f[i][0][0]=1;
f[1][1][a[1]]=1;
for (int i=2;i<=n;++i)
{ for (int j=1;j<=min(i,n/2);++j)
for (int k=a[i];k<=s;++k)
{
f[i%2][j][k]=max(f[(i-1)%2][j][k],f[(i-1)%2][j-1][k-a[i]]);
}
}
int ss=s;
int l=0;s/=2;
for (;;)
{ if (f[n%2][n/2][s+l])
{ cout<<min(s+l,ss-s-l)<<" "<<max(s+l,ss-s-l);
return 0;
}
if (f[n%2][n/2][s-l])
{ cout<<min(s-l,ss-s+l)<<" "<<max(s-l,ss-s+l);
return 0;
}
++l;
}
}