String 更改字符串的字母以获得最大分数

String 更改字符串的字母以获得最大分数,string,algorithm,search,string-hashing,String,Algorithm,Search,String Hashing,您将获得一个字符串,最多可以更改字符串中的Q个字母。您还将获得一个子字符串列表(每个子字符串有两个字符长),以及相应的分数。子字符串在字符串中的每次出现都会增加您的总分。可能达到的最高分数是多少 字符串长度解决这个问题的有效方法是使用动态规划 设L是从任何长度为2的评分子字符串开始的一组字母,以及一个特殊的字母“*”,表示除此之外的任何其他字母 设S(i,j,c)是使用j替换的字符串中可能的最大分数(直到索引i),其中字符串以字符c结尾(其中c在L中) 递归关系有点混乱(或者至少,我没有找到一个

您将获得一个字符串,最多可以更改字符串中的Q个字母。您还将获得一个子字符串列表(每个子字符串有两个字符长),以及相应的分数。子字符串在字符串中的每次出现都会增加您的总分。可能达到的最高分数是多少


字符串长度解决这个问题的有效方法是使用动态规划

设L是从任何长度为2的评分子字符串开始的一组字母,以及一个特殊的字母“*”,表示除此之外的任何其他字母

设S(i,j,c)是使用j替换的字符串中可能的最大分数(直到索引i),其中字符串以字符c结尾(其中c在L中)

递归关系有点混乱(或者至少,我没有找到一个特别漂亮的公式),但这里有一些代码可以计算出可能的最大分数:

infinity = 100000000

def S1(L1, L2, s, i, j, c, scores, cache):
    key = (i, j, c)
    if key not in cache:
        if i == 0:
            if c != '*' and s[0] != c:
                v = 0 if j >= 1 else -infinity
            else:
                v = 0 if j >= 0 else -infinity
        else:
            v = -infinity
            for d in L1:
                for c2 in [c] if c != '*' else L2 + s[i]:
                    jdiff = 1 if s[i] != c2 else 0
                    score = S1(L1, L2, s, i-1, j-jdiff, d, scores, cache)
                    score += scores.get(d+c2 , 0)
                    v = max(v, score)
        cache[key] = v
    return cache[key]

def S(s, Q, scores):
    L1 = ''.join(sorted(set(w[0] for w in scores))) + '*'
    L2 = ''.join(sorted(set(w[1] for w in scores)))
    return S1(L1, L2, s + '.', len(s), Q, '.', scores, {})

print S('bpdcg', 2, {'bz': 2, 'zd': 5, 'dm': 7, 'ng': 10})
还有一些优化空间:

  • 如果j为负值,计算不会提前终止
  • 当给出一个选择时,L2的每一个值都会被尝试,而只有能够完成d中评分词的字母才需要尝试

总的来说,如果评分词中有k个不同的字母,算法将在时间O(QN*k^2)内运行。通过上面的第二次优化,这可以减少到O(QNw),其中w是评分字数。

字符串和Q的最大长度是多少?@PhamTrung字符串最多可以是150个字符,Q最多可以是100个。这看起来像是背包问题。@n.m.以什么方式?我知道分配给每个子字符串的点如何与项目类似,背包如何表示字符串的长度,但是您如何解释您最多只能对原始字符串进行两次更改的事实?所有子字符串的长度都是2吗?您能否详细说明递归算法的解释?