Conversation
|
|
||
| この解法はO(k^n)であり、nかkの数が大きいときは避けたい解法である。なので次は動的計画法を用いた解法を考えていきたい。 | ||
| 全くわからなかったのでGeeksForGeeksの解法をみてみる。 | ||
| まずi個までのポストでの3つ以上同じ色が並ばない塗り方の通りをnum_of_ways[i]と定義する。すると、num_of_ways[i]はと定義する。すると、num_of_ways[i-1]の最後のポストの色と違う色を置く通り(num_of_ways[i-1]*(k-1))と、num_of_ways[i-2]の最後のポストの色と違う色を2つ連続でおく通り(num_of_ways[i-2]*(k-1))を足したものとなる。これをコードにしていく。 |
There was a problem hiding this comment.
num_of_ways[i-1]の最後のポストの色と違う色を置く通り(num_of_ways[i-1](k-1))と、num_of_ways[i-2]の最後のポストの色と違う色を2つ連続でおく通り(num_of_ways[i-2](k-1))を足したものとなる
これでどうしてnum_of_ways[i]を漏れなく重複なく表せますか?
There was a problem hiding this comment.
i番目まで制約を破らないように塗った際に、全てのパターンは以下の2パターンに分けることができます。
- i番目, i-1番目の色が違う
- i番目, i-1番目の色が同じ
全パターンを求めるためにまず1のパターンを求めます。
num_of_ways[i-1]のパターンの中で、ある色Aで終わる組み合わせはnum_of_ways[i-1] / k個存在していてi番目にA以外の色で塗ればi番目、i-1番目の色が違うパターンになります。そのパターンの数は(num_of_ways[i-1] / k) * (k - 1)個ありそれがk色分存在するためnum_of_ways[i-1] * (k - 1)通りになります。
次にパターン2の数を求めます。
これは i-2番目までのポストの塗り方がそれぞれあって、それらに i-1, i番目に同じ色を2つ連続で置くことで求めることができます。ただし3つ以上同じ色が並ぶことはできないため、i-2番目の色とは違う色を選ぶ必要があります。i-2番目の色に対して選べる色は k - 1 通りなので、num_of_ways[i-2] * (k - 1)通りになります。
これらの2パターンの組み合わせを足して、
num_of_ways[i]= num_of_ways[i-1] * (k - 1) + num_of_ways[i-2] * (k - 1)
となります。
There was a problem hiding this comment.
ありがとうございます。その通りだと思います。
i番目, i-1番目の色が違う
i番目, i-1番目の色が同じ
これらを変数に置く方法の方が、直感的かもしれません。
| ```Python | ||
| class Solution: | ||
| def num_ways(self, n: int, k: int) -> int: | ||
| num_of_ways = 0 |
There was a problem hiding this comment.
こちらのコメントをご参照ください。
h-masder/Arai60#18 (comment)
| if n == 1: | ||
| return k | ||
|
|
||
| num_of_ways = [0]*n |
There was a problem hiding this comment.
こちらのコメントをご参照ください。
mt2324/leetcode#2 (comment)
There was a problem hiding this comment.
配列の時だとそのクセが抜けておりました...
開けるように心がけます。
問題:https://www.lintcode.com/problem/514/
言語: Python3