当前位置: 代码迷 >> 综合 >> 清题笔记2020多校4 1004 Contest of Rope Pulling(01背包加随机化)
  详细解决方案

清题笔记2020多校4 1004 Contest of Rope Pulling(01背包加随机化)

热度:63   发布时间:2024-02-04 22:42:07.0

题目描述

拉绳,也叫拔河,是一种经典的游戏。张三组织了一班和二班的拉绳比赛。
一班有学生,二班有学生。张三需要从两个班中选出一部分学生,让一班与二班的学生竞争。
它也被允许不从一个班里挑选学生或选择所有的学生。
为了公平竞争,两队的总实力必须相等。为了让比赛更漂亮,张三想选择这样一组学生,让所有参赛者的总美丽价值最大化。
请帮助她确定最佳的总美容价值。

输入

输入的第一行给出测试用例的数量T(1≤T≤30)。

测试案例如下。

对于每个测试用例,第一行包含两个整数n,m(1≤n,m≤1000),代表1班和2班的学生人数。 接下来是(n+m)行,描述学生。ithline包含两个整数wi,vi(1≤wi≤1000,?109≤vi≤109),代表ITH学生的力量和美丽价值。第一批学生来自1班,其他学生来自2班。
所有测试用例中的(n+m)之和不超过104。

输出

对于每个测试用例,打印一条带有整数的行,表示最佳的总美感值。

样例输入

2
3 4
4 7
3 8
2 2
14
5 8
13
4 4
12
1000 -10000
200 3000
800 5000
# 样例输出
30
0

思路:

01背包加随机化,题意可以转换为有质量为正的和负的物品,求和为0时的最大价值。由于数组不能开太大,按顺序全是正的或负的会超范围,把数组随机化.定一个base作为初始值,开始背包问题。

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
const ll INF=1e15;
const int maxn=2e3+10;
const int maxdp=1e5+10;
const int base=5e4;
const int lim=1e5;
struct node{int w,v;
}a[maxn];
ll w[maxn],v[maxn];
ll temp[maxdp];
ll dp[maxdp];
void init(){fill(dp,dp+maxdp,-INF);fill(temp,temp+maxdp,-INF);dp[base]=0;temp[base]=0;
}
int main () {int T;scanf("%d",&T);while(T--){int n,m;scanf("%d%d",&n,&m);init();for(int i=1;i<=n+m;i++){scanf("%d%d",&a[i].w,&a[i].v);if(i>n){a[i].w=-a[i].w;}}random_shuffle(a+1,a+1+n+m);for(int i=1;i<=n+m;i++){for(int j=min(lim,(int)lim+(int)a[i].w);j-a[i].w>=0;j--){if(dp[j-a[i].w]!=-INF){temp[j]=max(dp[j],dp[j-a[i].w]+a[i].v);}}for(int j=0;j<=maxdp-1;j++){dp[j]=temp[j];}}printf("%lld\n",dp[base]);}
}
  相关解决方案