经典算法之博弈论 取球博弈

问题描述:

取球博弈.局面上有一堆球,二人博弈,每人一次只能取1,3,7或者8个球.要求输出局面有n个球时的胜负情况.



解题思路:

这里我提供两种题解,一种是纯递归求解,但纯递归CPU消耗过大,后面我还会提供动态规划+缓存的题解方法.



实现方式一:

*纯递归解题, 由于纯递归对CPU消耗过大,这里我以1到50个球的局面情况为例

public class Main {
	public static void main(String[] args) {
		for (int i = 1; i <= 50; i++) {    //i为球的总数
			System.out.println(i + ": " + fun(i));   //true为我方必赢 false为必输
		}
	}

	public static boolean fun(int n) {    //n为局面所剩的球数
		if (n == 0) return true;
		
		if (n > 1 && fun(n - 1) == false) return true;
		if (n > 3 && fun(n - 3) == false) return true;
		if (n > 7 && fun(n - 7) == false) return true;
		if (n > 8 && fun(n - 8) == false) return true;
		return false;
	}
}
github: https://github.com/striner/javaCode/blob/master/Take%20The%20Ball%20(Recursive)

编译运行:

经典算法之博弈论 取球博弈_第1张图片经典算法之博弈论 取球博弈_第2张图片



实现方式二:

*这里我用动态规划解决取球问题,由于递归时许多代码的重复运算严重造成了资源的浪费,故需将进行过运算的结果缓存起来.

缓存有很多实现方式,借用数组或者Map都可以实现,这里我以Map为例.

n个球,赢则true,输则false

ps: 我测试数据时偷懒未使用Scanner类输入数据,emmm...大家别学我...


代码如下:

public class Main {
	static Map map = new HashMap<>();
	public static void main(String[] args) {
		map.put(0, true);
		System.out.println(fun(1000));
	}

	public static boolean fun(int n) {
		
		if (map.get(n) != null) return map.get(n);
		
		Boolean b = false;
		if (n > 1 && fun(n - 1) == false) b = true;
		if (n > 3 && fun(n - 3) == false) b = true;
		if (n > 7 && fun(n - 7) == false) b = true;
		if (n > 8 && fun(n - 8) == false) b = true;
		
		map.put(n, b);
		return b;
	}
}

github: https://github.com/striner/javaCode/blob/master/Take%20The%20Ball(Dynamic%20Programming)


编译运行:

经典算法之博弈论 取球博弈_第3张图片

经典算法之博弈论 取球博弈_第4张图片





你可能感兴趣的:(博弈论,=====,算法,=====,动态规划,=====,数据结构,=====,##,java,=====,编程语言,=====,Map)