介绍
你长期以来一直是一个寻宝者。你很擅长解除陷阱,偷偷溜过当地人,通常在你的皮肤完好无损的情况下得到货物。这件事并不是真的让你担心,但真正让人大吃一惊的是每次探险结束后,总会有关于如何分赃的激烈争论。你和各种各样的人物一起工作,没有人同意每一件珍宝的价值。你需要想出一种尽可能公平地分割战利品的方法。
输入
对这个问题的输入将包括一个(非空)系列多达100个数据集。每个数据集将根据下面的描述进行格式化,并且不会有分隔数据集的空白行。
单个数据集有5个组成部分:
起始线-单线“START”
珍宝的数量-一个单一的整数与一个整数t,其中1 <=T<8,表示宝藏的数量。
猎人数量-一条带有一个整数的单线h,其中1 <= h <=6,表示寻宝者的数量。
珍宝价值列表-一系列的H线,每个猎人一个序列(猎人1线1,猎人2线2,等等)。每一行包含一个空间分隔的列表,估计该猎人的财富值。每一行的第一个估计值是宝藏1,第二个是宝藏2,等等,每个猎物的估计都会出现在每个猎人身上。每个估计将是严格小于10000的正整数。
结束线-单行,“END”
产量
对于每个输入数据集,将有一个精确的输出集,并且正好有一条空白线分离输出集。
每个输出集由多条线组成,其中每一条线代表一个猎人(以与相应的输入数据集相同的顺序列出)。每一行都有一份清单,列出了猎人的财宝,以及他们所收到的所有财宝的总现金价值。珍宝将按宝座编号升序排列,每条线上的所有值将是空间分隔的。
珍宝将以最公平的方式分给猎人们。划分财富的“最公平”方式是指在任何一个狩猎者收到的珍宝中,最高感知总价值和最低感知总价值之间的最小差异。换言之,找到最大限度地减少猎人获得“最”和最小的猎人之间的差异的分布。
不会有多个“公平”分布。
样本输入:
START
5
3
42 500 350 700 100
250 200 500 1000 75
150 400 800 800 150
END
START
5
3
42 500 350 200 100
250 200 500 1000 75
150 400 800 800 150
END
START
5
3
500 500 350 200 100
250 200 500 1000 75
150 400 800 800 150
END
样本输出:
4 700
3 5 575
1 2 550
1 4 5 342
3 500
2 400
1 2 1000
4 1000
3 5 950
代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int Max = 0x7fffffff;
struct Node{
int val[ 10 ];
}a[ 10 ];
struct Node2{
int num[ 10 ];
int cnt ,sum ;
}ans[ 10 ],dfs_ans[ 10 ];
int vis[ 10 ];
int diff;
bool flag[ 10 ];
void init(){
diff = Max;
memset( flag,false,sizeof( flag ) );
for( int i=0;i<10;i++ ){
for( int j=0;j<10;j++ ){
ans[ i ].num[ j ] = dfs_ans[ i ].num[ j ] = 0;
}
ans[ i ].cnt = ans[ i ].sum = dfs_ans[ i ].cnt = dfs_ans[ i ].sum = 0;
}
}
void init_vis( int n ){
int N = (1<<n);
for( int i=0;i<N;i++ ){
for( int j=0;j<n;j++ ){
if( i&(1<<j) ) vis[ j ] = 0;
else vis[ j ] = 1;
}
}
}
void dfs( int cur_hunter,int cur_treasure,int num_treasure,int hunter ){
if( cur_hunter==hunter&&cur_treasure==num_treasure ){
int t_max = dfs_ans[0].sum;
int t_min = dfs_ans[0].sum;
for( int i=1;i<hunter;i++ ){
t_max = max( t_max,dfs_ans[i].sum );
t_min = min( t_min,dfs_ans[i].sum );
}
if( t_max-t_min<diff ){
diff = t_max-t_min;
for( int i=0;i<hunter;i++ )
ans[i] = dfs_ans[i];
}
return ;
}
if( cur_hunter>=hunter ) return ;
int N = (1<<num_treasure);
for( int i=0;i<N;i++ ){
int t_cnt = 0;
bool p_flag = true;
for( int j=0;j<num_treasure;j++ ){
if( i&(1<<j) ) vis[ j ] = 0;
else {
vis[ j ] = 1;
t_cnt++;
if( flag[j]==true ) {
p_flag = false;
break;
}
}
}
if( p_flag==true&&( t_cnt+cur_treasure+hunter-cur_hunter-1 )<=num_treasure ){
int tt = 0;
dfs_ans[ cur_hunter ].sum = 0;
dfs_ans[ cur_hunter ].cnt = t_cnt;
for( int j=0;j<num_treasure;j++ ){
if( vis[j] == 1 ){
dfs_ans[ cur_hunter ].num[ tt++ ] = j;
flag[ j ] = true;
dfs_ans[ cur_hunter ].sum += a[ cur_hunter ].val[j];
}
}
dfs( cur_hunter+1,cur_treasure+t_cnt,num_treasure,hunter);
for( int j=0;j<tt;j++ ){
flag[ dfs_ans[ cur_hunter ].num[j] ] = false;
}
}
}
return ;
}
int main(){
int num_treasure,hunter;
char s[ 12 ];
int ca = 1;
while( scanf("%s",s)!=EOF ){
init();
scanf("%d%d",&num_treasure,&hunter);
for( int i=0;i<hunter;i++ ){
for( int j=0;j<num_treasure;j++ ){
scanf("%d",&a[i].val[j]);
}
}
scanf("%s",s);
if( num_treasure==1 ){
int m_min = a[0].val[0];
int m_num = 0;
for( int i=1;i<hunter;i++ ){
if( m_min>a[i].val[0] ){
m_min = a[ i ].val[0];
m_num = i;
}
}
if( ca!=1 ) printf("\n");
ca++;
for( int i=0;i<hunter;i++ ){
if( i==m_num ){
printf("1 %d\n",m_min);
}
else
printf("0\n");
}
continue;
}
dfs( 0,0,num_treasure,hunter );
if( ca!=1 ) printf("\n");
ca++;
for( int i=0;i<hunter;i++ ){
for( int j=0;j<ans[i].cnt;j++ ){
if( j==0 )
printf("%d",ans[i].num[j]+1);
else
printf(" %d",ans[i].num[j]+1);
}
if( ans[i].cnt>0 ) printf(" %d\n",ans[i].sum);
else printf("%d\n",ans[i].sum);
}
}
return 0;
}