You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何攻克Hackerrank的Fair Cut挑战?求DP递推关系思路

Fair Cut问题的动态规划解法思路

首先得说,你之前用中位数+双指针的思路能过10个测试用例已经不错了,但这个问题确实没法靠贪心彻底解决——一旦数组里有极端值或者分布不均匀,贪心就会掉链子,比如我碰到过一个例子:数组是[1,3,4,5,10],要选2个数给Li,贪心选中间的4和5得到的不公平度是21,但选3和5反而能得到20,更小。所以必须用动态规划来建模。

接下来我一步步给你推导递推关系,核心是先把数组排序,这是关键!因为排序后绝对值的计算可以直接转化为加减,不用再考虑正负。

第一步:问题转化与排序

先把数组从小到大排序,记为a₁ ≤ a₂ ≤ ... ≤ aₙ。这样一来,任何两个数的绝对值差都可以直接用大的减小的,不用判断顺序,这会极大简化后续的代价计算。

第二步:定义DP状态

我们需要两个二维数组:

  • dp[i][j]:表示在前i个数里选j个给Li时,能得到的最小不公平度。
  • g[i][j]:对应dp[i][j]的最优选择下,Li拿到的j个数的总和。(这个数组是关键,因为我们需要它来计算新增的不公平度)

另外预处理一个前缀和数组s,s[i] = a₁ + a₂ + ... + aᵢ,用来快速计算前i个数的总和。

第三步:初始状态

  • dp[0][0] = 0:0个数里选0个,不公平度为0。
  • g[0][0] = 0:对应的总和也是0。
  • dp[i][0] = 0:前i个数选0个给Li,不公平度为0(Li没数,自然没有差值)。
  • g[i][0] = 0:总和为0。
  • dp[0][j] = ∞(无穷大):0个数里选j>0个,不可能,用无穷大表示不可行。

第四步:状态转移

对于第i个数(也就是当前处理到aᵢ),我们有两种选择:分给Li,或者分给Lu。

选择1:把aᵢ分给Li

此时前i-1个数里已经选了j-1个给Li。新增的不公平度来自aᵢ和前i-1个数里分给Lu的那些数的差值——因为数组排序了,aᵢ比前i-1个数都大,所以每个差值都是aᵢ - y(y是前i-1个里Lu的数)。

前i-1个数里Lu的数有(i-1) - (j-1) = i-j个,它们的总和是s[i-1] - g[i-1][j-1](前i-1个数的总和减去Li拿到的j-1个数的总和)。所以新增的代价是:
aᵢ*(i-j) - (s[i-1] - g[i-1][j-1])

对应的总不公平度就是:

cost1 = dp[i-1][j-1] + aᵢ*(i-j) - (s[i-1] - g[i-1][j-1])

此时Li的总和更新为:

sum1 = g[i-1][j-1] + aᵢ

选择2:把aᵢ分给Lu

此时前i-1个数里已经选了j个给Li。新增的不公平度来自aᵢ和前i-1个数里Li的那些数的差值——同样因为排序,每个差值都是aᵢ - x(x是前i-1个里Li的数)。

Li的j个数总和是g[i-1][j],所以新增的代价是:
j*aᵢ - g[i-1][j]

对应的总不公平度就是:

cost2 = dp[i-1][j] + j*aᵢ - g[i-1][j]

此时Li的总和不变:

sum2 = g[i-1][j]

取最优解

我们选cost1和cost2里较小的那个作为dp[i][j],同时把对应的总和赋值给g[i][j]:

if cost1 < cost2:
    dp[i][j] = cost1
    g[i][j] = sum1
else:
    dp[i][j] = cost2
    g[i][j] = sum2

第五步:空间优化(可选)

因为计算dp[i][j]只需要用到dp[i-1][...]的状态,所以可以把二维数组改成一维的滚动数组,把空间复杂度从O(nk)降到O(k),对于n较大的情况(比如n=1000)会更高效。

最终答案

填充完整个dp数组后,dp[n][k]就是Li恰好拿到k个数时的最小不公平度。

这样建模的核心是利用排序后的有序性,把绝对值差的计算转化为可累加的代价,同时通过维护Li的总和来快速计算新增的不公平度,避免了重复计算。

内容的提问来源于stack exchange,提问作者Rahul Seetharaman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:42:13