【发布时间】:2018-06-20 12:19:45
【问题描述】:
我正在使用回溯递归解决以下问题。第一个代码“CoinGame1”提供了正确的解决方案,但第二个代码“CoinGame2”提供了错误的解决方案。我想,发生了一些不好的事情,因为我在递归调用之前先反转了字符串。
*硬币游戏:Alice 和 Bob 正在使用一堆硬币玩游戏。玩家依次从一堆硬币中挑选出几个硬币。每个玩家每回合可以选择 1、2 或 4 个硬币。每次允许玩家挑选硬币时, 获得最后一枚硬币的玩家为获胜者。众所周知,最后,当剩下1、2或4个硬币时,第一个回合的玩家肯定会根据需要选择1、2或4个硬币并获胜。例如,如果最后有 2 个硬币,而 Alice 是第一个选择的玩家,那么她肯定会选择 2 个硬币并获胜。给定硬币的数量和玩家的顺序(这意味着第一个和第二个挑选硬币的玩家),编写一个程序来打印获胜者的所有可能性 游戏中,
F(1, {爱丽丝,鲍勃}) 爱丽丝 F(6, {爱丽丝,鲍勃}) 爱丽丝, 鲍勃, 鲍勃, 爱丽丝, 鲍勃, 鲍勃 F(4, {爱丽丝,鲍勃}) 爱丽丝 F(3, {爱丽丝,鲍勃}) 鲍勃,鲍勃* f(6,{A,B}) / \ \ f(5,{B,A}) f(4,{B,A}) f(2,{B,A}) / | \ B 赢 B 赢 f(4,{A,B}) f(3,{A,B}) f(1,{A,B}) A胜/| \A胜 / | \ f(2,{B,A}) f(1,{B,A}) f(-1,{B,A}) B 赢 B 赢//解决方案1
public class CoinGame1
{
public static void Count(int n, String[] s) // n: no. of coins
//s:{"Alice","Bob"} (order)
{
if(n>0)
{
if(n==1 || n==2 || n==4) System.out.println( s[0] ); // if 1/2/4
//coins left, the one with first chance wins
else
{
Count(n-1,new String[]{s[1],s[0]});
Count(n-2,new String[]{s[1],s[0]});
Count(n-4,new String[]{s[1],s[0]});
}
}
}
public static void main(String[] args)
{
String[] order = new String[]{"A","B"};
Count(6,order);
}
}
java CoinGame1 一种 乙 乙 一种 乙 乙
//解决方案2
public class CoinGame2
{
public static void Count(int n, String[] s) // n: no. of coins
//s:{"Alice","Bob"} (order)
{
if(n>0)
{
if(n==1 || n==2 || n==4) System.out.println( s[0] ); // if 1/2/4
//coins left, the one with first chance wins
else
{
String temp = s[0]; s[0] = s[1]; s[1] = temp; // reverse s
Count(n-1,s);
Count(n-2,s);
Count(n-4,s);
}
}
}
public static void main(String[] args)
{
String[] order = new String[]{"A","B"};
Count(6,order);
}
}
java CoinGame2 一种 乙 乙 乙 乙 乙
【问题讨论】:
-
在您的第二个 sn-p 中,您正在改变数组,但是在所有迭代中都使用相同的数组实例。将
System.out.println(Arrays.asList(s));放在每个Count(...)之前。见stackoverflow.com/q/40480/1225328。 -
@sp00m 谢谢....第二个代码只给出了不正确的第四个值..我无法通过调试来理解。我尝试调试第二个代码,发现 f(-1,{B,A}) 正在返回 f(5,{B,A}) (而不是 f(5,{A,B}) ),最终调用 f(1,{B,A})) (而不是 f(1,{A,B}) )返回 B 。为什么 f(-1,{B,A}) 不返回 f(5,{A,B})?
标签: java recursion tail-recursion backtracking recursive-backtracking