Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで母音の遷移規則に従って作成できる文字列の数をカウントするプログラム

n が与えられたとき、以下の規則に従って生成できる長さ n の文字列の総数を求めることを考えます。

  • 各文字は小文字の母音 [a, e, i, o, u] のいずれかである
  • 「a」の後に続けられるのは「e」のみ
  • 「e」の後に続けられるのは「a」または「i」
  • 「i」の後に「i」を続けることはできない
  • 「o」の後に続けられるのは「i」または「u」
  • 「u」の後に続けられるのは「a」のみ

結果が非常に大きくなる可能性があるため、答えは 10^9 + 7 で割った余りを返します。

例として、入力が n = 2 の場合、出力は 10 になります。このとき生成できる2文字の文字列は、["ae", "ea", "ei", "ia", "ie", "io", "iu", "oi", "ou", "ua"] の10通りです。

解き方

この問題は動的計画法(DP)を用いることで効率的に解けます。ポイントは、「各母音で終わる文字列が何通りあるか」を状態として管理し、遷移規則に基づいて次の長さの状態へ順に更新していくことです。

具体的な手順は以下の通りです。

  • モジュール値 m = 10^9 + 7 を設定する
  • n が 0 の場合は 0 を返す
  • 5つの変数 a, e, i, o, u を用意し、すべて 1 で初期化する(長さ1の文字列は各母音について1通りずつ存在するため)
  • n - 1 回のループを実行し、各回で次の遷移を行う
    • a := e + i + u(「e」「i」「u」の後に「a」を付けられるため)
    • e := a + i(「a」「i」の後に「e」を付けられるため)
    • i := e + o(「e」「o」の後に「i」を付けられるため)
    • o := i(「i」の後に「o」を付けられるため)
    • u := i + o(「i」「o」の後に「u」を付けられるため)
  • 最後に (a + e + i + o + u) mod m を返す

なお、Pythonではタプルの同時代入を利用すると、右辺がすべて評価されてから一括で左辺に代入されるため、一時変数を用意せずに状態更新を簡潔に記述できます。

それでは、以下の実装例を見て理解を深めましょう。

実装例

class Solution:
def solve(self, n):
m = (10 ** 9 + 7)
if n == 0:
return 0
a = e = i = o = u = 1
for _ in range(n-1):
a, e, i, o, u = e+i+u, a+i, e+o, i, i+o
return (a + e + i + o + u) % m

ob = Solution()
print(ob.solve(3))

入力

3

出力

19

n = 3 の場合、19通りの文字列が生成できることが確認できます。この解法の時間計算量は O(n)、空間計算量は O(1) であり、n が非常に大きい場合でも高速に動作するのが特徴です。

  1. サイズ d の正十二角形を作れる組み合わせの数を求める C++ プログラム

    問題概要 整数 d が与えられたとします。ここで、一辺の長さが 1 の正方形タイルと正三角形タイルが無限枚あるものと考えます。これらのタイルを組み合わせて、一辺の長さが d の正十二角形(12 辺形)を作るとき、その作り方が何通りあるかを求めるのがこの問題です。答えが非常に大きくなる場合は、998244353 で割った余りを返します。 アプローチ この問題は、二項係数を利用することで効率的に解くことができます。結論から言うと、求めるべき答えは C(2d−1, d−1)、すなわち「2d−1 個の中から d−1 個を選ぶ組み合わせの総数」です。 階乗を直接計算すると値が急激に大きくなりオーバー

  2. 連続する「1」を含まないバイナリ文字列の数を数えるPythonプログラム

    この記事では、「連続する1が存在しないバイナリ文字列の総数を求める」という問題の解き方について、Pythonでの実装例を交えながら詳しく解説します。 問題文 問題: 正の整数 N が与えられます。このとき、長さ N のバイナリ文字列(0と1のみで構成される文字列)のうち、連続する「1」が一切含まれないものの総数を求めてください。 例えば N = 3 の場合、有効な文字列は「000」「001」「010」「100」「101」の5つとなり、「011」「110」「111」は連続する1を含むため除外されます。 アプローチ:動的計画法 この問題は動的計画法(DP)を使うことで効率的に解けます。各桁の状態を