题意:两班各选几人参加比赛,每个人都有体重和魅力值,要求在两边体重相等的情况下魅力值最大。
图片说明

分析:01背包问题,不过直接写的话复杂度是O(10^9)显然不行。(比赛时有人竟然用容量和为上界水过了
官方题解的优化:
通过随机化算法进行优化背包容量。(random_shuffle)
将所有选手随机排列然后依次算背包,背包的容量限定在范围图片说明 中即可,而这个 图片说明 足够大即可
题解证明:容量上界取:图片说明 .

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn=2e5+10;
const int up=1e5;
const ll inf=0x7f7f7f7f;

struct node{
    int w,v;
}a[maxn];

ll dp[2][maxn];

int main()
{
    int t,n,m;
    scanf("%d",&t);
    while( t-- )
    {
        scanf("%d%d",&n,&m);
        for( int i=1;i<=n+m;i++ )
        {
            int w,v;scanf("%d%d",&w,&v);
            w= i>n ? -w : w;
            a[i]={w,v};
        }
        n+=m;

        random_shuffle(a+1,a+1+n);
    //    random_shuffle(a+1,a+1+n);

        int lim=sqrt(n)*1000;
        for(int i=0;i<=1;i++ )
        {
            for( int j=0;j<=2*up;j++ ) dp[i][j]=-1e18;
        }

        dp[0][up]=0;
        int op=1;
        for( int i=1;i<=n;i++ )
        {
            for( int j=-lim;j<=lim;j++ )
            {
                dp[op][j+a[i].w+up]=max( dp[op^1][j+a[i].w+up],dp[op^1][j+up]+a[i].v);
            }
            op^=1;
        }
        printf("%lld\n",dp[op^1][up]);
    }
    return 0;
}