解説

NN 個の単語から ii 個の単語を選んで並べる方法は N×(N1)×(N2)××(Ni+1)N \times (N - 1) \times (N - 2) \times \cdots \times (N - i + 1) 通りあります。この値を P(N,i)P(N, i) とおきます。例えば、55 個の単語から 33 個の単語を選んで並べる方法は P(5,3)=5×4×3=60P(5, 3) = 5 \times 4 \times 3 = 60 通りあります。

この問題では単語を 11 個以上 NN 個以下選んで並べる場合の数を問われているため、答えは i=1NP(N,i)\displaystyle\sum_{i = 1}^N P(N, i) となります。

ii に対して毎回 P(N,i)P(N, i) の値を定義通り計算する (i=1Nj=Ni+1Nj を2重ループで計算する)\left( \displaystyle\sum_{i = 1}^N \displaystyle\prod_{j = N - i + 1}^N j \ を 2 重ループで計算する \right) アルゴリズムの時間計算量は Θ(N2)\Theta(N^2) となる (整数の加算と乗算の時間計算量が Θ(1)\Theta(1) であることを仮定しています) ため、2 秒間の実行時間制限に恐らく間に合いません。

しかし、P(N,i)P(N, i) の値は P(N,i1)P(N, i - 1) の計算結果を利用して求められることに注目すると時間計算量を Θ(N)\Theta(N) に削減することができ、この問題に正解できます。

P(N,i1)=N×(N1)×(N2)××{N(i1)+1}P(N, i - 1) = \textcolor{red}{N \times (N - 1) \times (N - 2) \times \cdots \times \{N - (i - 1) + 1\}}

P(N,i)=N×(N1)×(N2)××{N(i1)+1}×(Ni+1)P(N, i) \hspace{1.75em} = \textcolor{red}{N \times (N - 1) \times (N - 2) \times \cdots \times \{N - (i - 1) + 1\}} \times (N - i + 1)

=P(N,i1)×(Ni+1)\hspace{5.3em} = P(N, i - 1) \times (N - i + 1)

解答例 (C++)

おまけ

walking dictionary