Algorithm 如何使此DP在O(NH)中运行?

Algorithm 如何使此DP在O(NH)中运行?,algorithm,dynamic-programming,Algorithm,Dynamic Programming,我有一个有趣的问题让我困惑了一会儿。这是《算法导论》一书中关于动态规划的一个练习 你工作的电话公司最近接管了一个新城市的电话服务。您已被指定专门负责Main street上的电话线杆。从位置1到N有N根电线杆,电线杆i的高度为H[i]英尺,是[1,maxH]范围内的整数。市政府要求您使所有电线杆的高度相同。对于每个i,如果第i极具有高度h和(i−1) -th杆的高度为h',则必须缴纳C|h的税款−h′|。为了帮助实现这一目标,您可以将任何电杆的高度增加或减少到h高度,费用为(h[i]−h) ^2

我有一个有趣的问题让我困惑了一会儿。这是《算法导论》一书中关于动态规划的一个练习

你工作的电话公司最近接管了一个新城市的电话服务。您已被指定专门负责Main street上的电话线杆。从位置1到N有N根电线杆,电线杆i的高度为H[i]英尺,是[1,maxH]范围内的整数。市政府要求您使所有电线杆的高度相同。对于每个i,如果第i极具有高度h和(i−1) -th杆的高度为h',则必须缴纳C|h的税款−h′|。为了帮助实现这一目标,您可以将任何电杆的高度增加或减少到h高度,费用为(h[i]−h) ^2。你的任务是决定如何增加或减少每根杆子的高度,以便你的公司花费最少的钱。特别是,你必须平衡改变电杆高度的成本和你的公司必须支付的税款

(提示)您至少应该能够在O(NH^2)中完成,但实际上您所能做的最好的是O(HN)

到目前为止,我得到了O(NH^2)。我的想法是我们将初始化一个大小为HxN的矩阵M,每个条目M[h,i]代表第一个i极的最小成本,i极高度为h。我的目标是填写整个矩阵并检查最后一列,即确定对我们的问题来说,全球最低成本的最后一个极点

def DP_pole(H,hmax,C,N):
    initialize empty matrix M[H,N]
    for i from 1 to hmax: #first pole,no tax, only construction fee
        M[i,1] = (H[1] - i)**2
    for n from 2 to n: #column first
        for h from 1 to hmax: #row second
            construction = (H[n]-h)**2 # you pay this construction always
            minimum = min(M[1,n-1]+C|h-1|,......,M[hmax,n-1]+C|h-hmax|)
            M[h,n] = construction + minimum
    
    #------find minimum------#
    
    min = float("-inf")
    for h from 1 to hmax:
        if M[h,N] < min:
            min = M[h,N]
    return min
def DP_极(H、hmax、C、N):
初始化空矩阵M[H,N]
对于从1到hmax的i:#第一杆,无税,仅建筑费
M[i,1]=(H[1]-i)**2
对于从2到n的n:#列第一
对于从1到hmax的h:#第二行
构造=(H[n]-H)**2#您始终支付此构造
最小值=min(M[1,n-1]+C | h-1 |,…,M[hmax,n-1]+C | h-hmax |)
M[h,n]=结构+最小值
#------求最小值------#
最小值=浮动(“-inf”)
对于从1到hmax的h:
如果M[h,N]
但到目前为止,我得到的算法不能简化为O(HN),我想(也许?)。因为我使用的递归关系是一个“线性”关系,为了确定矩阵H的每个条目,我将搜索前面的整个列,它取O(H)。矩阵中总共有H*N个条目需要填写


任何提示或帮助都将不胜感激。我需要想出一个不同的、更聪明的递归关系吗?

您有正确的动态规划方法,但是对每个
h
执行这个O(hmax)操作太昂贵了:

minimum = min(M[1,n-1]+C|h-1|,......,M[hmax,n-1]+C|h-hmax|)
通过一点预处理,您可以在固定时间内为每个
h
计算该值

首先,考虑一个新的杆的税额。让我们:

downmin[h] = min(M[1,n-1]+C(h-1),......,M[h,n-1])
您可以用O(hmax)计算这个数组,从0向上计算到
hmax


完成这些计算后,对于每个
h
minimum=min(upmin[h],downmin[h])
,您当然可以在固定时间内进行计算。

建造费是我们必须支付的费用,以使第i杆达到设计高度h。我们必须平衡税收和前(i-1)极,以获得最低限度的税收。我正在考虑如何跳出上一篇专栏文章的线性搜索。它最终不会给我O(HN)。根据答案猜测,我们应该能够在O(1)中完成每个条目,最终能够得到一个O(HN)。这里有一个想法-在
dp[n][h]
dp[n][h+1]
之间,进行了大量重复计算。请注意,当您取最小值时,低于
h
的所有值仅增加1,高于
h
的所有值减少1。@Primusa Hi。我理解,每次更改h时,术语C | h-h'增加/减少C*1。但是为了计算dp[n,h],我仍然需要比较dp[n-1,1]和dp[n-1,hmax]。所以我在做“专栏式”。你建议“按行”吗?我不太明白。H是一个数组,不是一个数字,所以O(NH)没有意义。@MattTimmermans哦,对不起,我的意思是H_max,一个极点的最大高度。
if (h == hmax)
    upmin[h] = M[h,n-1]
else
    upmin[h] = min( M[h,n-1], upmin[h+1]+C )
downmin[h] = min(M[1,n-1]+C(h-1),......,M[h,n-1])