使用动态编程计算字符串

时间:2019-07-10 15:23:37

标签: c++ dynamic-programming

给出由大写字母组成的字符串s,即从“ A”到“ Z”。我们必须找出多少个字符串t的长度等于s的长度,并且这些字符串也由大写字母组成,并且满足以下条件:

  • 字符串t在字典上比字符串s大。
  • 当您以相反的顺序同时写st时,t的字典顺序仍然大于s

找出此类字符串t。这是我在使用dp的特定社论中找到的解决方案:

让F [i] [ok1] [ok2]是如果已经获得字符串T的前i-1个字符且ok1和ok2表示以下信息,则可以生成的字符串T的数目:

ok1 = 0表示T的前i-1个字符仍与S的对应t-1字符匹配。ok1 = 1表示T大于S。 ok2 = 0表示按相反的顺序,T中的前t-1个字符在字典上已经大于S中的相应字符。否则,ok2 =0。
令N为S的长度。当然,结果将为F [0] [0] [0]。我们可以用F [N + 1] [1] [1] = 1来初始化dp。我们将按i的降序计算F。对于每个i,ok1,ok2,我们尝试将所有可能的字符放在位置i上,以使T的字典顺序从不小于原始顺序的S:

//let s is 0-indexed
for (int i = N - 1; i > 0; i--)
    for (int ok1 = 0; ok1 <= 1; ok1++)
      for (int ok2 = 0; ok2 <= 1; ok2++) {
      //make sure that T is always lexicographically larger than S in original order
        for (char c = ok1 == 0 ? s* : 'A'; c <= 'Z'; c++) {
          int nextOk2 = ok2;
          if (c != s[pos]) {
            //if we put a character c > s[pos] in position pos of T then T became lexicographically larger than S in reversed order
            nextOk2 = c > s[pos];
          }
      f[pos][ok1][ok2] = (f[pos][ok1][ok2] + f[pos + 1][ok1 || c > s[pos]][nextOk2]) % MOD;
    }
  }

复杂度将为O(N×2×2×26)。

  • 我不明白的是为什么F [N + 1] [1] [1] = 1?
  • 此外,为什么最终答案存储在F [0] [0] [0]中?
  • 有人能用很小的钱就上述算法提供很好的解释吗?例如?

0 个答案:

没有答案