zoukankan      html  css  js  c++  java
  • 2020 Multi-University Training Contest 4 1012 Last Problem(01背包)

    题目

      http://acm.hdu.edu.cn/showproblem.php?pid=6804

    题意

      分别给出 n,m 对数(w,v),在 n 对 和 m 对中分别取出若干对使得 w 的和相等,在这个前提下使所有的 v 之和最大,问 v 最大值为多少。

    题解

      首先看到这个题意,第一时间想到对 n 和 m 分别跑一遍01背包最后在枚举 w 的值取出最大的那个,可是这样的话我们会发现跑一遍01背包就需要 1e9,时间上过不去。所以我们先将 m 对数的 w 取反,然后将 n 和 m 对数放一起同时跑,答案就是 dp[0] 了。为了将时间缩小我们将 n 和 m 对数放在一起随机打乱,使得数值能够在 0 附近震荡,在这种情况下当绝对数很大时能恢复到 0 的概率很小,所以就能将原来 1e6 的 dp 数组减小,只在 1e5 的范围内更新就好。

    #include <bits/stdc++.h>
    // #include <iostream>
    // #include <cstring>
    // #include <string>
    // #include <algorithm>
    // #include <cmath>
    // #include <cstdio>
    // #include <queue>
    // #include <stack>
    // #include <map>
    // #include <bitset>
    // #include <set>
    // #include <vector>
    // #include <iomanip>
    #define ll long long
    #define ull unsigned long long
    #define met(a, b) memset(a, b, sizeof(a))
    #define rep(i, a, b) for(int i = a; i <= b; ++i)
    #define bep(i, a, b) for(int i = a; i >= b; --i)
    #define lowbit(x) (x&(-x))
    #define MID (l + r) / 2
    #define ls pos*2
    #define rs pos*2+1
    #define pb push_back
    #define ios() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
    
    using namespace std;
    
    const int maxn = 1e6 + 1010;
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll mod = 1e9 + 7;
    const double eps = 1e-6;
    const double PI = acos(-1);
    
    struct node {
        ll w, v;
    }arr[maxn];
    
    ll dp[maxn], tail;
    
    int main() {
        srand(time(0));
        int T;
        scanf("%d", &T);
        while(T--) {
            rep(i, 0, maxn - 1) dp[i] = -INF;
            int n, m;
            scanf("%d%d", &n, &m);
            tail = 0;
            rep(i, 1, n) {
                tail++;
                scanf("%lld%lld", &arr[tail].w, &arr[tail].v);
            }
            rep(i, 1, m) {
                tail++;
                scanf("%lld%lld", &arr[tail].w, &arr[tail].v);
                arr[tail].w = -arr[tail].w;
            }
            random_shuffle(arr + 1, arr + 1 + tail);
            dp[100000] = 0;
            rep(i, 1, tail) {
                if(arr[i].w > 0) {
                    bep(j, 200000, arr[i].w) {
                        dp[j] = max(dp[j], dp[j - arr[i].w] + arr[i].v);
                    }
                }
                if(arr[i].w < 0) {
                    rep(j, 0, 200000 + arr[i].w) {
                        dp[j] = max(dp[j], dp[j - arr[i].w] + arr[i].v);
                    }
                }
            }
            printf("%lld
    ", dp[100000]);
        }
        return 0;
    }
  • 相关阅读:
    Flask学习笔记1:基础知识
    Git学习笔记3:下载指定项目的单个文件或文件夹
    Tensorflow学习笔记6:解决tensorflow训练过程中GPU未调用问题
    Python学习笔记32:UDP协议链接
    Python学习笔记31:图片URL批量转存到本地
    软件安装笔记3:tesseract-ocr for mac和homebrew
    软件安装笔记2:Aria2百度云加速下载器
    软件安装笔记1:破解安装SecureCRT for mac及解决中文乱码问题
    forward(转发)与redirect(重定向)的区别
    剑指Offer_编程题_丑数
  • 原文地址:https://www.cnblogs.com/Ruby-Z/p/13414900.html
Copyright © 2011-2022 走看看