您的位置:首页 > 运维架构

HDU6804 Contest of Rope Pulling(0/1背包+随机数)

2020-08-12 23:35 991 查看

HDU6804 Contest of Rope Pulling(0/1背包+随机数)

Description
Rope Pulling, also known as Tug of War, is a classic game. Zhang3 organized a rope pulling contest between Class 1 and Class 2.
There are n students in Class 1 and m students in Class 2. The ith student has strength wi and beauty-value vi. Zhang3 needs to choose some students from both classes, and let those chosen from Class 1 compete against those chosen from Class 2. It is also allowed to choose no students from a class or to choose all of them.
To be a fair contest, the total strength of both teams must be equal. To make the contest more beautiful, Zhang3 wants to choose such a set of students, that the total beauty-value of all participants is maximized. Please help her determine the optimal total beauty-value.
Input
The first line of the input gives the number of test cases, T(1≤T≤30). T test cases follow.
For each test case, the first line contains two integers n,m(1≤n,m≤1000), representing the number of students in Class 1 and Class 2.
Then (n+m) lines follow, describing the students. The ith line contains two integers wi,vi(1≤wi≤1000,−109≤vi≤109), representing the strength and the beauty-value of the ith student. The first n students come from Class 1, while the other m students come from Class 2.
The sum of (n+m) in all test cases doesn’t exceed 104.
Output
For each test case, print a line with an integer, representing the optimal total beauty-value.
Sample Input
2
3 4
4 7
3 8
2 2
1 4
5 8
1 3
4 4
1 2
1000 -10000
200 3000
800 5000
Sample Output
30
0

题意

有两个班级,一班有n个人,二班有m个人,每个人都有力气值和美丽值,从两个班分别选出任意个人,要让他们的力气之和相同(可以全选也可以不选),并使它们的美丽值最大。
实际上我们可以把题目转化成01背包问题:n+m个物品,把力气作为cost,把美丽值作为value,一班的cost做负贡献,二班的cost做正贡献,最后取dp[0]即可。
题目给的范围太大,我们可以随机打乱数组,使得范围大幅度缩小。这里使用了random_shuffle函数。因为存在负值,所以把背包整体往右挪一段。从dp[-50000]到dp[50000]变成dp[0]到dp[100000],最后取中值dp[50000]。
dp要开long long,初始化要非常小才够用。背包那一段不能用max,会TLE。
来源于https://blog.csdn.net/weixin_44751481/article/details/107720319

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<functional>
#include<map>
#include<unordered_map>
#define lowbit(x) ((x)&-(x))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e6+10,NN=2e3+10,LEN=20;
const ll MOD=1e9+7,INF=0x3f3f3f3f3f3f3f3f;
const ull seed=31;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
struct Pack{
ll w,v;
}pack[N];
ll n,m;
ll dp[N];
void init(){
for(int i=0;i<=N;i++) dp[i]=-INF;
dp[50000]=0;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
init();
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n+m;i++){
scanf("%lld%lld",&pack[i].w,&pack[i].v);
if(i<=n) pack[i].w=-pack[i].w;
}
random_shuffle(pack+1,pack+1+n+m);
for(int i=1;i<=n+m;i++){
if(pack[i].w>0){
for(int j=100000;j>=pack[i].w;j--) if(dp[j-pack[i].w]+pack[i].v>dp[j]) dp[j]=dp[j-pack[i].w]+pack[i].v;
}
else{
for(int j=0;j<=100000+pack[i].w;j++) if(dp[j-pack[i].w]+pack[i].v>dp[j]) dp[j]=dp[j-pack[i].w]+pack[i].v;
}
}
printf("%lld\n",dp[50000]);

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: