题意:给你C个小组(C<=5),S个数值(S<=10, C*2>=S)。要将这S个数值分配给C个小组,每小组最多分配两个数值。求最优的分配方式,使得下面 IMBALANCE 的值最小。
其中AM = 所有数值之和 / C; CMi = 第i小组的数值之和;
#include<iostream> #include<algorithm> #include<cstdio> #include<vector> #include<cmath> #include<cstring> using namespace std; const int maxn=12; int a[maxn],s,c,q[maxn]; double ave,ans; int p[maxn][4],res[maxn][4]; void dfs(int idx) { int i,j; if(idx>s)///分配完全 { double sum=0; int i,j; for(i=1;i<=c;i++) { sum+=fabs(q[i]-ave); } if(sum<ans) { ans=sum; for(i=1;i<=c;i++)//赋值 { res[i][0]=0; for(j=1;j<=p[i][0];j++) { res[i][0]++; res[i][j]=p[i][j]; } } } return; } for(i=1; i<=c; i++)///尝试把第 idx 个分别放在这 c 个腔里!! { if(p[i][0]>=2) continue; p[i][0]++; p[i][p[i][0]]=a[idx]; q[i]+=a[idx]; dfs(idx+1); q[i]-=a[idx]; p[i][0]--; } } void init() { for(int i=0;i<=c;i++) { q[i]=0; for(int j=0;j<=3;j++) { p[i][j]=0; res[i][j]=0; } } } int main() { int cas=1; while(scanf("%d%d",&c,&s)!=EOF) { int i,j,sum=0; for(i=1; i<=s; i++) { scanf("%d",&a[i]); sum+=a[i]; } init(); ans=200000000; ave=sum*1.0/c; dfs(1); printf("Set #%d\n",cas++); for(i=1;i<=c;i++) { printf(" %d:",i-1); for(j=1;j<=res[i][0];j++) { printf(" %d",res[i][j]); }printf("\n"); } printf("IMBALANCE %.5f\n\n",ans); } return 0; }