题意: n+m对元组<w, v>,求当前n个元组的子集和后m个元组中的子集满足:sigma(w)相等时候,两个子集的sigma(v)和最大。n, m<1e3, 0<w<1e3, -1e9<v<1e9。时间:5S
题解:直接暴力跑背包,复杂度O(n*sigma(w)),有1e9了。。。但是还是可以过的
#include <bits/stdc++.h> #define IO_read ios::sync_with_stdio(false);cin.tie(0) #define fre freopen("in.txt", "r", stdin) #define _for(i,a,b) for(int i=a; i< b; i++) #define _rep(i,a,b) for(int i=a; i<=b; i++) #define inf 0x3f3f3f3f #define lowbit(a) ((a)&-(a)) using namespace std; typedef long long ll; template <class T> void read(T &x) { char c; bool op=0; while(c=getchar(), c<'0'||c>'9') if(c=='-') op=1; x=c-'0'; while(c=getchar(), c>='0'&&c<='9') x=x*10+c-'0'; if(op) x=-x; } template <class T> void write(T x) { if(x<0) putchar('-'), x=-x; if(x>=10) write(x/10); putchar('0'+x%10); } const int maxn=1e6+5; const long long inf_ll= (ll)1<<61; vector<pair<long long, long long> > vec; int T, n, m; long long f1[maxn], f2[maxn]; int main() { fre; read(T); while(T--) { read(n), read(m); long long x, y; int sum1=0, sum2=0, sum=0; _rep(i, 1, n) read(x), read(y), vec.push_back(make_pair(x, y)), sum1+=x; _rep(i, 1, m) read(x), read(y), vec.push_back(make_pair(x, y)), sum2+=x; _rep(i, 1, min(sum1, sum2)) f1[i]=f2[i]=-inf_ll; f1[0]=f2[0]=sum=0; _for(i, 0, n){ sum+=vec[i].first; for(int j=sum; j>=vec[i].first; j--) f1[j]=max(f1[j], f1[j-vec[i].first]+vec[i].second); } sum=0; _for(i, n, n+m){ sum+=vec[i].first; for(int j=sum; j>=vec[i].first; j--) f2[j]=max(f2[j], f2[j-vec[i].first]+vec[i].second); } long long ans=0; _rep(i, 1, min(sum1, sum2)) ans=max(ans, f1[i]+f2[i]); printf("%lld ", ans); vec.clear(); } return 0; }