/* 多重背包,其实对于这部分的内容不是很理解的,但是还是做对了,很奇怪的 */ #include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N = 55; int main() { int n; int val[N], kind[N]; int dp[100000]; while( cin >> n) { if(n < 0) break; int sum = 0; for(int i = 1; i <= n ; i++) { cin >> val[i] >> kind[i]; sum += val[i] * kind[i]; } int v = sum / 2; memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) for(int j = 1; j <= kind[i]; j++) for(int k = v; k >= val[i]; k--) dp[k] = max(dp[k], dp[k - val[i]] + val[i]); cout<<sum - dp[v] << " " << dp[v] << endl; } } 母函数解法: #include<iostream> #include<algorithm> #include<cmath> using namespace std; int dp[250005],df[250005]; int main() { int n,sum,a[51],b[51],ave,x,y; while(cin>>n&&n>=0) { sum=0; for(int i = 0;i < n; i++) { cin >> a[i] >> b[i]; sum += a[i] * b[i]; } for(int i=0;i<=sum;i++) { dp[i] = 0; df[i] = 0; } df[0]=1; for(int i = 0;i < n; i++) { for(int j=0;j<=sum;j++) for(int k = 0;k <= a[i]*b[i] && k + j <= sum;k += a[i]) dp[j+k] += df[j]; for(int j = 0; j <= sum; j++) { df[j] = dp[j]; dp[j] = 0; } } int max1 = 2500050; for(int i = 0;i <= sum; i++) { if(df[i] == 0) continue; int t = abs(sum - 2*i); if(t < max1) { max1 = t; x = i; y= sum-i; } } cout<< max(x,y) << " " << min(x,y) << endl; } }