説明:
アリスとボブは、彼らが交代で、ゲームをプレイします。アリス上側のハンド開始。
最初は、ボード上の番号Nがあります。各プレイヤーのターンでは、プレイヤーは、以下のことを実行する必要があります。
0 <X <N、およびN%X == 0を満たし、Xとして選択されます。
ボード上の交換用デジタルXのN - N.付き
プレイヤーはこれらの操作を実行できない場合は、ゲームを失うことになります。
唯一のアリスは、場合にのみ、ゲームでの勝利、そうでない場合はfalse Trueを返します。2人のプレイヤーがゲームに参加するための最良の状態にあると仮定します。
例1:
入力:2
出力:真
の解釈:アリスは1を選択し、ボブは、操作することはできません。
例2:
入力:3
出力:偽
の解釈:アリスは1を選択し、ボブはまた、1つを選択し、アリスは操作できません。
ヒント:
1 <= N <= 1000
アイデア:
この質問は次の2つの方法で解決することができ、1は数学的帰納法で、1は動的プログラミング、動的プログラミングはここにある主程度です。
数学的帰納:
最終結果は、伝送を占めて勝利2、1会計処理されなければなりません。
電流が奇数の場合、奇数の除数が奇数であるか、または1つだけなので、次は偶数でなければならないこと。
現在の数が約偶数の場合、偶数奇数が偶数であってもよい1であってもよく、このように直接マイナス1、次は奇数です。
したがって、その後も勝つ、負けるために奇妙です。
動的計画:
すべての溶液未満であるか、または、上記に基づいて、再帰後を見つけるためにNに等しいです。
状態遷移は:いくつかの程度がある場合、私は(つまり、負けの場合)Falseに存在している、はず電流iはTrueです。もしそうでない場合は、とFalse
Javaの:
クラスソリューション{ パブリック ブール divisorGame(INT N){ 場合(N <= 1 ){ 戻り 偽。 } 場合(N == 2 ){ 戻り 真。 } ブール []タグ= 新しい ブール [N + 1 ]。 タグ[ 1] = 真。 タグ[ 2] = 偽。 以下のために(INT I 3 =; I <tag.length; I ++ ){ タグ[I] =falseに; // 番号範囲について、複数のI / 2時間よりも、Iの数は約存在しない ため(INT J = 1、J <I / 2、J ++ ){ IF(%I J == 0 &&タグ[I - J ] == falseに){ タグ[I] = trueに、 BREAK ; } } } 戻りタグ[N]; } }
結果:
python3:
クラスソリューション: DEF divisorGame(自己、N:整数) - > BOOL: もし N == 1 : 戻り偽 であれば N == 2 : リターン真 タグ = Falseのための I における範囲(0、N + 1 )] タグ[ 2] = Trueの ための I における範囲(3、N + 1 ) のための J での範囲(1、I // 2 ): もし I%2 == 0 やタグ[I - J] ==偽: タグ[i]は = 真の ブレーク リターンタグ[N]
結果: