Description
Input
Output
Sample Input
2 10 1 20 1 3 10 1 20 2 30 1 -1
Sample Output
20 10 40 40
多重背包的板子题
题意:给出每个物体的价值和物体的数量,如何分使得A,B所得价值最接近并且A的价值不能小于B
思路:将总和平分后,就是一道01背包题了
顺带讲解一下:std::ios::sync_with_stdio(false);
放在int main 下面。 但是当用了后就不可以在使用scanf和printf否则无限re;
因为关闭了同步,就不允许在使用stdio.h中的输入输出函数了;
AC代码:
#include<iostream> #include<cstdio> #include <cstring> #include <algorithm> using namespace std; int dp[255000],n; void wq(int v) { for(int i=v;i<=n;i++) dp[i]=dp[i]>dp[i-v]+v?dp[i]:dp[i-v]+v; } void b01(int v) { for(int i=n;i>=v;i--) dp[i]=dp[i]>dp[i-v]+v?dp[i]:dp[i-v]+v; } void dc(int a,int b) { if(a*b>n) wq(a); else { int k=1; while(k<b) { b01(k*a); b-=k; k*=2; } b01(b*a); } } int main() { std::ios::sync_with_stdio(false);//*黑科技 int t,i,o,v[55],m[55]; while(cin>>t,t>=0) { memset(dp,0,sizeof(dp)); o=0; for(i=0;i<t;i++) { cin>>v[i]>>m[i]; o+=v[i]*m[i]; } n=o/2; for(i=0;i<t;i++) dc(v[i],m[i]); cout<<o-dp[n]<<" "<<dp[n]<<endl; } }