博客
关于我
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/

    你可能感兴趣的文章
    Pandas 的 DataFrame 详解-ChatGPT4o作答
    查看>>
    pandas 读取excel数据,以字典形式输出
    查看>>
    Pandas 读取具有浮点值的 csv 文件会导致奇怪的舍入和小数位数
    查看>>
    pandas 适用,但仅适用于满足条件的行
    查看>>
    pandas 重新采样到每月的特定工作日
    查看>>
    pandas :按移位分组和累加和(GroupBy Shift And Cumulative Sum)
    查看>>
    pandas :检测一个DF和另一个DF之间缺失的列
    查看>>
    Pandas-从具有嵌套列表列表的现有列创建动态列时出错
    查看>>
    Pandas-通过对列和索引的值求和来合并两个数据框
    查看>>
    pandas.columns、get_dummies等用法
    查看>>
    pandas.DataFrame.copy(deep=True) 实际上并不创建深拷贝
    查看>>
    pandas.read_csv()的详解-ChatGPT4o作答
    查看>>
    PANDAS.READ_EXCEL()输出‘;溢出错误:日期值超出范围‘;而不存在日期列
    查看>>
    pandas100个骚操作:再见 for 循环!速度提升315倍!
    查看>>
    Pandas:对给定列求和 DataFrame 行
    查看>>
    Pandas、Matplotlib、Pyecharts数据分析实践
    查看>>
    Pandas中文官档~基础用法2
    查看>>
    Pandas中文官档~基础用法5
    查看>>
    Pandas中文官档~基础用法6
    查看>>
    Pandas中的GROUP BY AND SUM不丢失列
    查看>>