題意:分物品,使得兩份的價值差最小。
方法:相當於求容量為sum/2的最大價值,所以,所需費用=當前物品價值
#define N 55int v[N],m[N];int dp[50*50*100+100];int V;//容量void zeroone(int cost,int val){//費用,價值 int i; for(i=V;i>=cost;i--){ if(dp[i]<dp[i-cost]+val){ dp[i] = dp[i-cost]+val; } }}void complete(int cost,int val){//費用,價值 int i; for(i=cost;i<=V;i++){ if(dp[i]<dp[i-cost]+val){ dp[i] = dp[i-cost]+val; } }}void multi(int cost,int val,int cnt){//費用,價值,數量 if(cost*cnt>=V){ complete(cost,val); return ; } int k = 1; while(k<cnt){ zeroone(k*cost,k*val); cnt -= k; k *= 2; } zeroone(cnt*cost,cnt*val);}int main(){FRE; int n; while(scanf("%d",&n) && n>=0){ int i,j,k;int sum = 0; for(i=0;i<n;i++){ scanf("%d%d",&v[i],&m[i]); sum+=v[i]*m[i]; } for(i=0;i<=sum/2;i++){ dp[i] = 0; } V = sum/2;//相當於求容量為sum/2的最大價值 for(i=0;i<n;i++){ multi(v[i],v[i],m[i]);//注意所需費用等於當前物品價值 } i = sum/2; printf("%d %d\n",sum-dp[V],dp[V]); } return 0;}