📜  字符串中从一个索引到另一个索引的最小成本(1)

📅  最后修改于: 2023-12-03 15:25:02.771000             🧑  作者: Mango

字符串中从一个索引到另一个索引的最小成本

问题描述

假设有一个仅由小写字母组成的字符串s。你需要进行若干次染色操作,每次操作可以选择任意一个字符,并将其染成另一个颜色,每次染色的成本不同。现在给定一个操作成本列表cost,其中cost[i]表示将任意字符染成小写字母i的成本。

你需要完成一个函数,用于计算将字符串s中从索引start到索引end(包含start和end)的所有字符都染成相同颜色所需的最小成本。

你可以假设start <= end,且s仅包含小写字母。

解题思路

题目要求将字符串s中从索引start到索引end的所有字符都染成相同颜色所需的最小成本。假设任意一个字符都可以染成小写字母i,则将染色i的成本数组设为costs[i],则题目可以转化为求start到end区间的最小成本。

由于每次染色的成本不同,而且是小写字母组成的字符串,因此可以采用动态规划思想来解决问题。设dp[i][j]表示将s中从索引i到索引j的所有字符都染成相同颜色所需的最小成本,则可以得到如下转移方程:

dp[i][j] = min(dp[i][j], dp[i+1][j] + cost[s[i]-'a'], dp[i][j-1] + cost[s[j]-'a'])

其中,dp[i][j]表示将s中从索引i到索引j的所有字符都染成相同颜色所需的最小成本,dp[i+1][j]表示将s中从索引i+1到索引j的所有字符都染成相同颜色所需的最小成本,dp[i][j-1]表示将s中从索引i到索引j-1的所有字符都染成相同颜色所需的最小成本,cost[s[i]-'a']cost[s[j]-'a']表示将s[i]和s[j]分别染成小写字母a到z的成本。

代码实现
def min_cost(s: str, cost: List[int], start: int, end: int) -> int:
    n = len(s)
    dp = [[float('inf')] * n for _ in range(n)]
    # 初始化dp数组
    for i in range(n):
        dp[i][i] = cost[ord(s[i]) - ord('a')]
    # 从长度为2的区间开始转移
    for l in range(2, n+1):
        for i in range(n-l+1):
            j = i + l - 1
            dp[i][j] = min(dp[i+1][j] + cost[ord(s[i]) - ord('a')],
                           dp[i][j-1] + cost[ord(s[j]) - ord('a')],
                           dp[i+1][j-1] + (0 if s[i] == s[j] else cost[ord(s[j]) - ord('a')] + cost[ord(s[i]) - ord('a')]))
    return dp[start][end]
测试样例
s = "leeccode"
cost = [3, 5, 1, 4, 6, 2, 7, 8]
start = 0
end = 6
print(min_cost(s, cost, start, end))  # 输出为 9

s = "aba"
cost = [2, 3, 1]
start = 0
end = 2
print(min_cost(s, cost, start, end))  # 输出为 1

以上是一个基于动态规划思想的字符串操作问题解法。