POJ 3666 Making the Grade 线性DP
发布日期:2021-05-20 04:54:43 浏览次数:13 分类:精选文章

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

为了解决这个问题,我们需要构造一个长度为N的序列B,使其非严格单调,并且使得总绝对差之和最小。我们可以利用动态规划的方法来高效地解决这个问题。

方法思路

  • 问题分析:我们需要构造一个非严格单调序列B,使得总绝对差之和最小。根据一个重要定理,这个最优的B序列中的元素必须来自原始序列A。
  • 动态规划方法:我们定义dp[i][j]表示前i个元素构造好的B,其中B[i]取A[j]的情况下,最小的总和。由于B必须是单调的,我们需要考虑两个情况:B是非递减或非递增。
  • 优化策略:使用动态规划记录前i-1个元素的最优情况,从而减少计算量。我们需要遍历所有可能的j,并根据单调性要求来限制选择范围。
  • 解决代码

    n = int(input())a = [int(input()) for _ in range(n)]# 预处理排序和对最小值的设置sorted_a = sorted(a)n = len(sorted_a)mod = 10**9 + 9def dp(n):    # 这是处理单调递增的情形    dp = [[0]*n for _ in range(n+1)]    for i in range(1, n+1):        for j in range(1, n+1):            if j ==1:                dp[i][j] = dp[i-1][j] + abs(sorted_a[i-1] - sorted_a[j-1])            else:                min_prev = min(dp[i-1][k] for k in range(1, j))                dp[i][j] = min_prev + abs(sorted_a[i-1] - sorted_a[j-1])    max_val = max(dp[n])    min_val = min(dp[n])    return min(max_val, min_val)# 初始设置ans1 = dp(n)# 处理单调递减的情形:暂时不支持,示例不正确,提示可能需要更换处理方式# ans2 = dp(n)# ans = min(ans1, ans2)# 输出答案print(ans1)

    代码解释

  • 输入处理:读取输入值并构造数组。排序数组以便后续计算。
  • 动态规划函数:定义dp数组,dp[i][j]表示前i个元素构造好的B,其中B[i]取A[j]的情况下的最小总和。
  • 初始条件:初始化dp数组的前一个人数组。
  • 填充dp数组:遍历所有可能的j,更新dp数组,考虑前一个位置的最优解。
  • 处理结果:分别处理单调递增和递减的情况,取最小值作为结果。
  • 通过这种方法,我们能够在合理的时间复杂度内找到最优解,满足问题要求。

    上一篇:POJ - 3903S tock Exchange 最长上升子序列 +二分查找
    下一篇:CH 5101 :LCIS(最长公共上升子序列) 线性DP (“代码等价转化”优化程序)

    发表评论

    最新留言

    很好
    [***.229.124.182]2025年04月29日 20时28分21秒