1025.除数ゲーム
アリスとボブは一緒にゲームをし、交代でゲームをします。アリスは最初にゲームを始めました。
当初、黒板には数字のNがありました。各プレイヤーのターンで、プレイヤーは以下のアクションを実行する必要があります。
0 <x <NおよびN%x == 0を満たす任意のxを選択します。
黒板の数字NをN-xに置き換えます。
プレイヤーがこれらの操作を実行できない場合、ゲームに負けます。
アリスがゲームに勝った場合にのみTrueを返し、それ以外の場合はFalseを返します。両方のプレーヤーが最高の状態でゲームに参加すると仮定します。
示例 1:
输入:2
输出:true
解释:爱丽丝选择 1,鲍勃无法进行操作。
示例 2:
输入:3
输出:false
解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。
提示:
1 <= N <= 1000
回答:
このようなゲームの問題は、動的計画法のアイデアによって解決されることがよくあります。
つまり、配列dpを使用して、数値がNの場合の勝ち負けの状況にアクセスできます。
分析を通じて、動的計画問題の境界、つまり、1番と2番の勝ち負けの状況を見つけることができます。
次に、問題の分析を開始しました。
私たちの目標はアリスの勝ち負けの状況を見つけることなので、最初に配列dpにすべての0を格納させることができます。つまり、アリスは任意の数の場合にすべての数を失い、次にアリスが勝った数だけを尋ねて配列に入力します。再び。
では、アリスはいつ勝ちますか?
このタイプのゲームの問題には、多くの場合、最良の状態でゲームに参加するという条件があります。つまり、勝利の計画がある場合、状態が最良であるため、最良の状態であることに注意してください。計画を考える必要があります。アリスに勝つように頼むために1つを送る場合、つまり、アリスがいくつか取った後、ボブに残されているのは確実に失われる計画です。
いくつかの例からわかります。
アリスの番でテイクがない場合、Nが2の場合、アリスが勝ちます。
Nが3のとき、アリスは1を取り、2に変わります。このとき、状況は上記と同じですが、キャラクターがアリスからボブに変わるため、ボブが上記の結論から勝ったと直接結論付けます。この時点で、私たちは新しい結論を出しました。それが誰かの番であり、彼がNを3としない場合、彼は負けなければなりません。
Nが4の場合、アリスが1を取ると、ボブの対応するNは3になり、上記の結論から、彼は負けなければならないことがわかります。
アリスが2を取る場合、上記の結論から、ボブの対応するNは2であり、ボブが勝つ必要があることがわかります。
したがって、以下の数値の結論が以前の基準に基づいていることを見つけるのは難しくありません。したがって、数値がNのときにアリスの勝ち負けを取得したい場合は、0-N-1を格納するだけで済みます。勝ち負けのステータス。Nの場合を計算します。
したがって、ループトラバーサルを作成します。ボブを失う解決策を見つけるだけでよいので、アリスを勝つことができます(私たちが最初であるため)。したがって、Nを決定した後、問題のために最初に見つける必要があります。 (1、N)範囲内のNの因数なので、1-Nをトラバースするループを作成し、その範囲内の因数を見つけて、合計Nから見つけた因数を減算します。新しいNに対応する状態はステータスは次のようになります。
配列dpはアリスの勝ち負けに対応しているように見えることに注意してください。実際、最初のステップを削除すると合計Nが新しいNになるため、ボブの勝ち負けにも対応します。最初のプレーヤーがボブになりました。
コード:
bool divisorGame(int N){
int dp[N+1];
if(N==1)
{
return 0;
}
if(N==2)
{
return 1;
}
memset(dp,0,sizeof(int)*(N+1));
dp[1]=0;
dp[2]=1;
for(int i=3;i<=N;i++)
{
for(int j=1;j<i;j++)
{
if(i%j==0&&dp[i-j]==0)//此时即对应找到一个因数且总数减去因数后留下的这个数形成的新N对应先手的是一种必输的情况
//而此时由于爱丽丝已经操作过了,所以此时的先手对应的就是鲍勃了,所以这里也就是鲍勃的必输情况了
{
dp[i]=1;
}
}
}
return dp[N];
}