博客
关于我
「一本通 5.1 例 1」石子合并 ( 区间dp + 环的处理 + 非贪心算法 )
阅读量:97 次
发布时间:2019-02-26

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

为了解决这个问题,我们需要找到一种方法来合并石子,使得在两种不同的合并方案下,得分总和分别最大化和最小化。由于石子是环形排列的,我们需要考虑循环的情况,通常这可以通过将问题转化为线性结构来处理。

方法思路

  • 动态规划 (DP) 算法:我们可以使用动态规划来解决这个问题。定义两个状态:

    • maxx[i][j] 表示从第 i 堆到第 j 堆合并后的最大得分。
    • minn[i][j] 表示从第 i 堆到第 j 堆合并后的最小得分。
  • 状态转移方程

    • 对于每个区间 [i, j],我们可以将其分割为 [i, k] 和 [k+1, j],然后合并这两个区间得到的结果。
    • maxx[i][j] 取决于 maxx[i][k]maxx[k+1][j] 的最大值。
    • minn[i][j] 取决于 minn[i][k]minn[k+1][j] 的最小值。
  • 处理环形结构:由于石子是环形排列的,我们将其转换为线性结构来处理。具体来说,我们将数组扩展到 2n,然后处理所有可能的区间。

  • 解决代码

    import sysdef main():    n = int(sys.stdin.readline())    a = list(map(int, sys.stdin.readline().split()))    a = [0] + a + a[:n]  # 处理环,变成线结构,长度为 2n-1    sum_ = [0] * (2 * n + 1)    for i in range(1, 2 * n + 1):        sum_[i] = sum_[i-1] + a[i]    INF = float('inf')    max_dp = [[0] * (2 * n + 1) for _ in range(2 * n + 1)]    min_dp = [[INF] * (2 * n + 1) for _ in range(2 * n + 1)]    for i in range(1, 2 * n + 1):        max_dp[i][i] = 0        min_dp[i][i] = 0    for l in range(2, n + 1):        for i in range(1, 2 * n - l + 2):            j = i + l - 1            for k in range(i, j):                current_max = max_dp[i][k] + max_dp[k+1][j] + (sum_[j] - sum_[i-1])                if current_max > max_dp[i][j]:                    max_dp[i][j] = current_max                current_min = min_dp[i][k] + min_dp[k+1][j] + (sum_[j] - sum_[i-1])                if current_min < min_dp[i][j]:                    min_dp[i][j] = current_min    max_total = 0    min_total = INF    for i in range(1, n+1):        j = i + n - 1        if max_dp[i][j] > max_total:            max_total = max_dp[i][j]        if min_dp[i][j] < min_total:            min_total = min_dp[i][j]    print(min_total)    print(max_total)if __name__ == "__main__":    main()

    代码解释

  • 读取输入:读取输入的堆数 n 和每堆石子的数量。
  • 处理环形结构:将环形结构转换为线性结构,处理所有可能的区间。
  • 计算前缀和:计算前缀和数组 sum_,用于快速计算区间和。
  • 初始化 DP 数组:初始化 max_dpmin_dp 数组,用于存储最大和最小得分。
  • 填充 DP 表:根据状态转移方程填充 max_dpmin_dp 数组。
  • 处理环形结构:找到环形结构中的最大和最小得分,并输出结果。
  • 该方法通过动态规划有效地解决了环形结构下的石子合并问题,确保了计算的正确性和效率。

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

    你可能感兴趣的文章
    php微信 开发笔记,微信WebApp开发总结笔记
    查看>>
    php微信公众号开发access_token获取
    查看>>
    php微信公众号开发微信认证开发者
    查看>>
    php微信公众号开发用户基本信息
    查看>>
    php怎么将对象变成数组,php怎么将对象转换成数组
    查看>>
    RabbitMQ - 消息堆积问题的最佳解决方案?惰性队列
    查看>>
    php怎样比较两数大小,jquery如何判断两个数值的大小
    查看>>
    PHP性能监控 - 开启xhprof(一)
    查看>>
    PHP性能监控 - 怎么看xhprof报告(二)
    查看>>
    php截取字符串代码,PHP字符串截取_php
    查看>>
    php截取字符串,无乱码
    查看>>
    php手冊,php手冊之變量范圍
    查看>>
    PHP手机号码归属地查询API接口
    查看>>
    PHP执行耗时脚本实时输出内容
    查看>>
    PHP扩展安装
    查看>>
    PHP扩展数据库连接参数说明详解
    查看>>
    php把get参数放入数组_php怎么将数组转为url参数?
    查看>>
    php接口返回数据 用echo 还是return?
    查看>>
    php接口返回状态,大家一般怎么规范接口返回内容
    查看>>
    php接收formdata上传的多个文件,使用formData()上传多个文件
    查看>>