Given an array of integers (with at least two elements), I need to choose at least one element of each adjacent pair of elements in the array in a way that costs me the least. Then, return the cost and elements chosen.
For example,

[50, 30, 40, 60, 10, 30, 10]

我们 Select 30作为对(50,30)和对(30,40).然后,我们 Select 40作为对(40,60)和10作为对(60,10),(10,30).最后,10对(30,10).所以我们得到了30 + 40 + 10 + 10 = 90.

另一个例子,

[60, 100, 70]

有两种可能的 Select :[60,70]或[100].但是,最优解是[100],总共100个,小于60 + 70.因此,算法应该 Select 100.

我的问题是,我只成功地编写了一个返回最低成本的代码,而没有保存使用的元素.

My Code in Python

arr = [50, 30, 40, 60, 10, 30, 10]
min_sum = [0] * len(arr)
min_sum[0] = arr[0]
min_sum[1] = arr[1]

for i in range(2, len(arr)):
    choice1 = min_sum[i-1] + arr[i]
    choice2 = min_sum[i-2] + arr[i]
    min_sum[i] = min(choice1, choice2)

res = min(min_sum[-1], min_sum[-2])
print(res)

推荐答案

当只考虑直到元素i的数组时,将cost(i)称为最优解的成本,此问题有一个简单的递归公式:

cost(i) = min(
    arr[i] + cost(i-1),
    arr[i-1] + cost(i-2),
)

例如,数组[50,30,40,60,10,30,10]的成本是

10 + cost for [50, 30, 40, 60, 10, 30]
30 + cost for [50, 30, 40, 60, 10]

这种复发的基本情况是:

cost(0) = 0
cost(1) = 0
cost(2) = min(arr[0],arr[1])

这种递归关系导致了一个简单的迭代代码:

def cost(a):
    if len(a) <= 1:
        return 0
    elif len(a) == 2:
        return min(a)
    cost_iminus2 = 0
    cost_iminus1 = min(a[:2])
    for i in range(2,len(a)):
        cost_i = min(
            arr[i] + cost_iminus1,
            arr[i-1] + cost_iminus2,
        )
        cost_iminus2, cost_iminus1 = cost_iminus1, cost_i
    return cost_i

您可以轻松地修改此代码,以记住和中使用了哪些元素:

def selection(a):
    if len(a) < 2:
        return 0, []
    elif len(a) == 2:
        return min(a), [min(a)]
    cost_iminus2, selection_iminus2 = 0, []
    cost_iminus1, selection_iminus1 = min(a[:2]), [min(a[:2])]
    for i in range(2,len(a)):
        cost_i = min(
            a[i] + cost_iminus1,
            a[i-1] + cost_iminus2,
        )
        if cost_i == a[i] + cost_iminus1:
            selection_i = [*selection_iminus1, a[i]] # need to copy
        elif cost_i == a[i-1] + cost_iminus2:
            selection_i = selection_iminus2 # no need to copy
            selection_i.append(a[i-1])
        else:
            raise ValueError("unreachable branch")
        cost_iminus2, cost_iminus1 = cost_iminus1, cost_i
        selection_iminus2, selection_iminus1 = selection_iminus1, selection_i
    return cost_i, selection_i

输出:

>>> selection([50, 30, 40, 60, 10, 30, 10])
(90, [30, 40, 10, 10])
>>> selection([60,100,70])
(100, [100])

Python相关问答推荐

Polars LazyFrame在收集后未返回指定的模式顺序

追溯(最近最后一次调用):文件C:\Users\Diplom/PycharmProject\Yolo01\Roboflow-4.py,第4行,在模块导入roboflow中

标题:如何在Python中使用嵌套饼图可视化分层数据?

将数据框架与导入的Excel文件一起使用

管道冻结和管道卸载

Pandas计数符合某些条件的特定列的数量

可以bcrypts AES—256 GCM加密损坏ZIP文件吗?

如何使regex代码只适用于空的目标单元格

如何在两列上groupBy,并使用pyspark计算每个分组列的平均总价值

如何删除重复的文字翻拍?

mdates定位器在图表中显示不存在的时间间隔

如何在Gekko中处理跨矢量优化

Python日志(log)库如何有效地获取lineno和funcName?

Pandas:计数器的滚动和,复位

在matplotlib中重叠极 map 以创建径向龙卷风图

如果服务器设置为不侦听创建,则QWebSocket客户端不连接到QWebSocketServer;如果服务器稍后开始侦听,则不连接

启动线程时,Python键盘模块冻结/不工作

Matplotlib中的曲线箭头样式

对于数组中的所有元素,Pandas SELECT行都具有值

大Pandas 中的群体交叉融合