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;
}

 

posted @ 2020-07-31 13:50  N_Yokel  阅读(237)  评论(0编辑  收藏  举报