基于动态编程的字符串

时间:2018-01-21 13:00:40

标签: algorithm dynamic dynamic-programming

我在动态编程中遇到这些问题,我需要提供基于动态编程的解决方案:

我们有长度为n的字符串,只包含{A,B,C} charachters.string只有在连续不包含3个A并且最多包含一个'B'时才是“胜利者”。 例: 有43个“获胜者”字符串,长度为4。 我需要建议一个计算长度为n的“获胜”字符串数的算法。它需要以O(n)复杂度运行。

到目前为止我的想法是: 3个参数:n-当前字符串的长度,bCount = 1,aCount = 2。 在每次迭代中,n减少1.如果我们使用b使得bCount减少1.如果我们使用A使得aCount减少1但是如果插入了任何其他字符则它初始化为2。

我需要使其正式和清晰,希望您能帮我填补空白并使解决方案正式化。

我真的很努力地解决它,如果有人能帮助我,我将非常感激。

提前谢谢。

1 个答案:

答案 0 :(得分:1)

首先让我们看看B.你或者没有B,因此只有A和C的长度为n的字符串,或者你有一个带有1 B的字符串和2个子字符串,累计长度为n - 1,只有A和C因此,如果您可以计算任何长度的字符串的所有有效A和C组合,其余的变得容易。

function winners(n) {
    let sum = combos[n]
    for (let i = 0; i < n; i++)
        sum += combos[i] * combos[n - i - 1]
    return sum
}

如何计算A,C组合?您可以使用动态编程(始终查看以A,C和AA结尾的字符串数量):

combos = [1, 2]
endsInA = 1
endsInC = 1
endsInAA = 0
for (let i = 2; i <= n; i++) {
    combos[i] = (endsInA + endsInC) * 2 + endsInAA
    let c = endsInC
    endsInC = endsInA + endsInAA + c
    endsInAA = endsInA
    endsInA = c
}

它是(endsInA + endsInC) * 2 + endsInAA,因为在以A或C结尾的那些之后,您可以放置​​A或C,而在以AA结尾的那些之后,您只能放置C.更新规则也很容易理解。你有尽可能多的字符串以AA结尾,因为你的字符串以A结尾,而尽可能多的字符串以A结尾,因为你的字符串以C结尾。 C可以放在所有字符串后面,所以它只是之前所有可能结局的总和。您也可以先更新,然后只取所有结局的总和来获得组合数。

Everything put together and optimized for a demo

计算组合需要O(n),计算获胜者需要O(n),因此整体复杂度为O(n)。