zoukankan      html  css  js  c++  java
  • POJ

    题目大意

    (N(N le 100)) 头奶牛,没有头奶牛有两个属性 (s_i)(f_i),两个范围均为 ([-1000, 1000])
    从中挑选若干头牛,(TS = sum s[choose], TF = sum f[choose])
    求在保证 (TS)(TF) 均为非负数的前提下,(TS+TF)最大值。

    样例

    有 5 头牛,下面分别是每头牛的两个属性
    5
    -5 7
    8 -6
    6 -3
    2 1
    -8 -5
    选择第 1、3、4 三头牛为最优解
    虽然加上 2 号,总和会更大,但是 TF 会变成负数,不合法
    

    分析

    • 首先从问题入手,先搞特殊情况:如果两个属性均为负数,果断舍弃,因为它一直在做负贡献
    • 一个物品有两个属性,会很自然想到二维费用背包,每个物品的价值为两个属性的和,也就是两种费用的和,这样定义其实意义并不大,而且时间复杂度为 (O(N*S*F)),最大会到 (10^8),应该会超时。
    • 由于价值直接是两者的和,所以我们没必要单独构造一个价值,而是把其中的一维改成价值即可,即用 (S_i) 当作费用,(F_i) 当作价值,最后扫一遍求最大和就可以了
    • 另外一个棘手的问题就是负数的问题:
      • 对于价值来说,正负都不影响,直接正常跑背包求最大值即可
      • 当费用为非负数时,没什么影响,正常跑 01 背包求最值,背包容积倒叙处理即可,(f[j] = max {f[j], f[j-s_i]+f_i})
      • 当费用为负数时,如果直接用上述的式子,(j-S_i > j),而背包容积倒叙的话,(f[j-s_i]) 会先于 (f[j]) 被计算。如果直接这样写,会变成完全背包的样子,不妥。因此只需要把容积改成正序循环即可。
      • 由于下标不能为负数,我们可以将 (0) 点改成 (100*1000),这样的话,即使所有物品的费用都为负数,下标也依旧处在合法的范围内。此时背包的容积也就相应变成了 ([0~200000])
      • 注意跑背包的时候的边界即可
      • 最后统计时,当费用不小于 (100000) 时才表示 (TS) 的和为非负数,找到所有价值为非负数的那些,最后求两者和的最大值即可。

    部分代码

    心情好的时候再加
    
  • 相关阅读:
    网站测试中如何做好安全性测试
    Web安全性测试总结
    文件上传验证绕过技术总结
    Burp Suite使用介绍
    Burpsuite教程与技巧之HTTP brute暴力破解
    burpsuite绕过本地javascripte上传文件
    文件上传漏洞演示脚本之js验证
    上传验证绕过
    Burp Suite详细使用教程
    关于post和get传递参数的区别
  • 原文地址:https://www.cnblogs.com/kuangbiaopilihu/p/12074191.html
Copyright © 2011-2022 走看看