拈游戏采用减治法解决:(且是减一操作,及每次看前一个状态的结果;这里是递归形式)
下面图是相关概念的解释
具体的求法通过下面的两个例子解释
1、leetcode_292(单堆拈游戏)
题目:桌子上有一堆石头,每一次你们轮流取1至3颗石头。最后一个取走石头的人就是赢家。第一轮由你先取。
根据题设条件:
当n∈[1,3]时,先手必胜。
当n == 4时,无论先手第一轮如何选取,下一轮都会转化为n∈[1,3]的情形,此时先手必负。
当n∈[5,7]时,先手必胜,先手分别通过取走[1,3]颗石头,可将状态转化为n == 4时的情形,此时后手必负。
当n == 8时,无论先手第一轮如何选取,下一轮都会转化为n∈[5,7]的情形,此时先手必负。
……
以此类推,可以得出结论:
当n % 4 != 0时,先手必胜;否则先手必负。
public class Solution {
public boolean canWinNim(int n) {
return n%4 != 0;
}
}
2、双堆求解
题目:如果有两堆火柴,每次只能从一堆中拿一根,或者两堆中各拿一根。拿走最后一根火柴的是赢家。
根据题设条件:
当n,m =[1,0]时,先手必胜。
当n,m =[1,1]时,先手必胜。
当n,m =[2,0]时,先手拿一次为[1,0],此时先手必负。
当n,m =[2,1]时,先手拿一次可以为[2,0],故先手胜。
当n,m =[2,2]时,先手拿一次[2,1]或者[1,1],故先手必负。
当n,m =[3,0]时,先手拿一次可以为[2,0],故先手必胜。
当n,m =[3,1]时,先手拿一次可以为[2,0],故先手必胜。
当n,m =[3,2]时,先手拿一次可以为[2,2],故先手必胜。
当n,m =[3,3]时,先手拿一次可以为[2,2],故先手必胜。
当n,m =[4,0]时,先手拿一次[3,0],故先手必负。
当n,m =[4,1]时,先手拿一次可以为[4,0],故先手必胜。
当n,m =[4,2]时,先手拿一次[3,1]or[3,2]or[4,1],故先手必负。
当n,m =[4,3]时,先手拿一次可以为[4,2],故先手必胜。
当n,m =[4,4]时,先手拿一次[4,3]or[3,3],故先手必负。
……..
以此类推,可以得出结论:
当n % 2 != 0 and m % 2 != 0时,先手必胜;否则先手必负。