博客
关于我
POJ2976 Dropping tests(二分+01分数规划)
阅读量:174 次
发布时间:2019-02-28

本文共 1889 字,大约阅读时间需要 6 分钟。

为了解决这个问题,我们需要找到一种方法来确定在允许删除 k 个测试成绩的情况下,剩下的 n-k 个测试的平均分的最大值。我们可以使用二分查找来确定这个最大平均值。

方法思路

  • 问题分析:我们需要找到一个子集,使得删除 k 个测试成绩后,剩下的测试成绩的平均分最大化。平均分的计算公式为总分除以总题数,因此我们需要在总分和总题数之间找到一个平衡点。

  • 二分查找:我们使用二分查找来确定最大的平均值。对于每个中间值 mid,我们需要检查是否存在一个子集,使得这个子集的总分之和至少为 mid 倍的总题数。

  • 贪心策略:对于每个中间值 mid,我们计算每个测试成绩对该中间值的贡献值,并选择贡献值最大的 n-k 个测试成绩。这样可以确保我们对每个中间值进行最优的检查。

  • 转换问题:我们将每个测试成绩转换为贡献值 s_i = a_i - mid * b_i,这样我们就可以通过选择最大的 n-k 个贡献值来确定是否存在满足条件的子集。

  • 解决代码

    import sysdef main():    input = sys.stdin.read().split()    ptr = 0    while True:        n = int(input[ptr])        k = int(input[ptr+1])        ptr += 2        a = list(map(int, input[ptr:ptr+n]))        ptr += n        b = list(map(int, input[ptr:ptr+n]))        ptr += n                if n == 0 and k == 0:            break                if k == 0:            total = sum(a)            total_b = sum(b)            avg = total / total_b            print(round(avg))            continue                S = sum(a)        T = sum(b)        low = 0.0        high = 100.0        best = 0.0        epsilon = 1e-9                while high - low > epsilon:            mid = (low + high) / 2            s = []            for i in range(n):                si = a[i] - mid * b[i]                s.append(si)            s.sort()            sum_s = 0.0            for i in range(n - k):                sum_s += s[i]            if sum_s >= 0:                best = mid                low = mid + epsilon            else:                high = mid - epsilon                avg = best        print(round(avg + epsilon / 2))if __name__ == "__main__":    main()

    代码解释

  • 读取输入:从标准输入读取数据,解析测试用例的数量和每个测试用例的参数。
  • 特殊情况处理:如果 k 为 0,直接计算并输出平均分。
  • 二分查找:设置 low 和 high 为初始值,使用二分查找来确定最大的平均值 mid。
  • 贡献值计算:对于每个 mid,计算每个测试成绩的贡献值,并选择最大的 n-k 个贡献值。
  • 检查可行性:如果选择的 n-k 个贡献值的总和大于等于 0,说明当前 mid 是可行的,可以尝试更高的 mid;否则,尝试更低的 mid。
  • 输出结果:确定最大的平均值,并将其四舍五入到最近的整数输出。
  • 这种方法确保了我们能够高效地找到最优解,时间复杂度主要由二分查找和排序决定,为 O(n log n),适用于给定的输入规模。

    转载地址:http://shjj.baihongyu.com/

    你可能感兴趣的文章
    python判断文件是空的,如果是空的,就删除
    查看>>
    python判断密码是否正确_python密码判断是否符合要求的方法
    查看>>
    python判断字符串包含中文_Python 判断字符串是否包含中文
    查看>>
    python删除第一行_Python 乱码指北:一行删掉根目录
    查看>>
    Python删除列表元素的三种方法
    查看>>
    python初步学习-python数据类型-集合(set)
    查看>>
    python列表生成字典_Python中将字典转换为列表的方法
    查看>>
    python列表对应元素合并为列表及判断一个列表是几维
    查看>>
    python列表去重复后按照顺序_从包含不可共元素的Python列表中删除重复元素,同时保留顺序?...
    查看>>
    python列表前几个_python之列表
    查看>>
    python列表元组
    查看>>
    Python列表/元组/字典和集合使用
    查看>>
    python列表 行列选择_python_pandas_dataframe_行列选择_切片操作
    查看>>
    python列表
    查看>>
    python列出当前目录、子目录和文件的脚本
    查看>>
    python+flask计算机毕业设计骨科门诊患者档案管理系统(程序+开题+论文)
    查看>>
    python+flask计算机毕业设计高校体测管理系统的设计与实现(程序+开题+论文)
    查看>>
    Python切片对象和__getitem__
    查看>>
    python+flask计算机毕业设计高校体育竞赛成绩管理系统的设计与实现(程序+开题+论文)
    查看>>
    python+flask计算机毕业设计高校体育赛事系统(程序+开题+论文)
    查看>>