hdu6804 Contest Of Rope Pulling // DP
作者:互联网
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6804
给出两个班的人,每个人具有力量与颜值两个属性。要求在两个班级中分别选取任意个人,使得各班力量总和相同,求总颜值的最大值。
01背包 ?——> 取负优化
由于数据较大,求和的话我们的内存伤不起。
因而选择将一个班级同学的力量取负,转而求DP[0]的max。
又根据数组下标非负性,找个maxn再向右挪一波——> 求DP[mid]
一寸长 一寸强
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #include<iomanip> 6 #include<vector> 7 #include<random> 8 9 #define ll long long 10 #define INF 1ll << 62// 11 using namespace std; 12 const int maxn = 1e5 + 10; 13 //通过随机数组元素の顺序,达到缩小maxn的目的 14 //取(-5e4,5e4),原本答案位于dp[0],但由于dp数组的正号性,直接右移5e4,取maxn=1e5 15 struct node 16 { 17 ll u; 18 ll v; 19 }; 20 21 int n, m; 22 ll dp[maxn]; 23 24 int main(){ 25 int T;cin >> T; 26 while(T--) 27 { 28 cin >> n >> m; 29 vector<node>v; 30 ll a, b; 31 for(int i = 1 ; i <= n ; i++){ 32 scanf("%lld %lld",&a,&b); 33 v.push_back({a ,b}); 34 } 35 for(int i = 1 ; i <= m ; i++){ 36 scanf("%lld %lld",&a,&b); 37 v.push_back({-a ,b}); 38 }//B班改为负 39 40 random_shuffle(v.begin(),v.end());//数组随机化 41 for(int i = 0 ; i < maxn ; i++) dp[i] = -INF; 42 43 const int mid = 5e4; 44 dp[mid] = 0; 45 for(int i = 0 ; i < m + n ; i++){//vector从零开始 46 if(v[i].u > 0){//等号放在下面好像不行 47 for(int j = mid * 2; j >= v[i].u ; j--){//j - v[i].u >= 0 48 dp[j] = max(dp[j], dp[j - v[i].u] + v[i].v); 49 } 50 }else if(v[i].u < 0){ 51 for(int j = 0 ; j <= mid * 2 + v[i].u ; j++){//j - v[i].u <= maxn 52 dp[j] = max(dp[j], dp[j - v[i].u] + v[i].v); 53 } 54 }else{//长得好看但没力气的人处处受欢迎。社会风气√ 55 for(int j = 0 ; j <= mid * 2 ; j++){ 56 dp[j] = max(dp[j], dp[j] + v[i].v); 57 } 58 } 59 //正负两组分别向mid方向汇聚,- ... MID ... + 60 } 61 62 printf("%lld\n",dp[mid]); 63 64 } 65 66 return 0; 67 } 68 //数对是真好用
标签:blog,int,distribute,Rope,Pulling,DP,include,hdu6804,dp 来源: https://www.cnblogs.com/ecustlegendn324/p/13498756.html