1. 程式人生 > 實用技巧 >HDU 6804 Contest of Rope Pulling(揹包)

HDU 6804 Contest of Rope Pulling(揹包)

題意: 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\n", ans); vec.clear(); } return 0; }