1、说的是杭电以前分家的时候,财产要尽可能的均匀分给两个兄弟。现在告诉你价值为n的物品有m件,你的任务就是把这些东西尽可能的分成两份。然后输出最后每家分的的财产总和。最大的总在最前面········


代码如下:

这一道题只要理解01背包、完全背包、多重背包就可以做了,属于简单题。。。。


/*
 * 1711_2.cpp
 *
 *  Created on: 2013年7月30日
 *      Author: Administrator
 */

#include <stdio.h>
#include <string.h>
#define N 50
//int max(int a , int b){
//	return (a>b)?a:b;
//}
//
//int min(int a ,int b){
//	return (a>b)?b:a;
//}
int max(int a ,int b){
	return (a > b)?a:b;
}

int min(int a ,int b){
	return (a > b)?b:a;
}

int f[N*N*N + 5],c[N+5],amount[N+5],V ;

void ZeroOnePack(int cost,int weight)
{
	int j;
	for(j=V;j>=cost;j--){
		f[j]=max(f[j],f[j-cost]+weight);
	}
}


void CompletePack(int cost , int weight){
	int v;
	for( v = cost ; v <=V  ; v++){
		f[v] = max(f[v],f[v-cost] + weight);
	}

}
void MultiplePack(int cost ,int weight , int amount){
	if(cost*amount >= V){
		CompletePack(cost,weight);
		return ;
	}
	int k = 1;
	while( k < amount){
		ZeroOnePack(k*cost,k*weight);
		amount -= k;
		k<<=2;
	}
	ZeroOnePack(amount*cost,amount*weight);
}



int main(){

	int i,n,sum ;

	while(scanf("%d",&n),n >= 0){

		 sum = 0;
		for( i = 0 ; i < n ; ++i){
			scanf("%d%d",&c[i],&amount[i]);

			sum +=  c[i]*amount[i];
		}

		V = sum/2;
		memset(f,0,sizeof(f));

		for( i = 0 ; i < n ; ++i ){
			MultiplePack(c[i],c[i],amount[i]);

		}
		printf("%d %d\n",max(f[V],sum-f[V]),min(f[V],sum - f[V]));



	}
	return 0;
}