經典演算法之博弈論 取球博弈
阿新 • • 發佈:2019-01-07
問題描述:
取球博弈.局面上有一堆球,二人博弈,每人一次只能取1,3,7或者8個球.要求輸出局面有n個球時的勝負情況.
解題思路:
這裡我提供兩種題解,一種是純遞迴求解,但純遞迴CPU消耗過大,後面我還會提供動態規劃+快取的題解方法.
實現方式一:
*純遞迴解題, 由於純遞迴對CPU消耗過大,這裡我以1到50個球的局面情況為例
github:https://github.com/striner/javaCode/blob/master/Take%20The%20Ball%20(Recursive)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; } }
編譯執行:
實現方式二:
*這裡我用動態規劃解決取球問題,由於遞迴時許多程式碼的重複運算嚴重造成了資源的浪費,故需將進行過運算的結果快取起來.快取有很多實現方式,借用陣列或者Map都可以實現,這裡我以Map為例.
n個球,贏則true,輸則false
ps: 我測試資料時偷懶未使用Scanner類輸入資料,emmm...大家別學我...
程式碼如下:
public class Main { static Map<Integer, Boolean> 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)