1. 程式人生 > >leetcode——464. 我能贏嗎

leetcode——464. 我能贏嗎

logs html ren etc min red ota esp space

技術分享圖片

  參考https://www.cnblogs.com/grandyang/p/6103525.html

  思路是遍歷每一種可能性,得出必勝的走法。然而,用遞歸會存在很多的重復計算,所以可用動態規劃存儲下計算的狀態,用map<int,bool>存儲,其中int對應current,考慮技術分享圖片,所以可以用int來存儲1~20的數字是否使用,比如1,就相當於1|current 即將第一位 置1 ,以此類推。

  首先判斷,如果maxChoosableInteger >= desiredTotal ,則先手必勝

  如果全部的和 小於 desiredTotal 則都是輸的

  剩余情況采用循環遍歷,然後將對應狀態存儲下來,若能贏,則返回 true

// Study.cpp: 定義控制臺應用程序的入口點。
//

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <string>
#include <algorithm>
#include <sstream>
#include <set>
#include <stack>
#define
INT_MAX 2147483647 // maximum (signed) int value #define INT_MIN (-2147483647 - 1) // minimum (signed) int value ; #define Min(x,y) (x)<(y)?(x):(y) using namespace std; int Max(int a, int b) { return a > b ? a : b; } bool Helper(int length, int total, int used, unordered_map<int
, bool> &map) { if (map.count(used)) return map[used]; for (int i = 0; i < length; i++) { int current = (1 << i); //判斷當前數字是否已經存在路徑裏面 if ((current & used) == 0) { if (total <= i + 1 || !Helper(length, total - (i+1), used | current, map)) { map[used] = true; return true; } } } map[used] = false; return false; } bool canIWin(int maxChoosableInteger, int desiredTotal) { //首先判斷,如果maxChoosableInteger >= desiredTotal ,則先手必勝 if (maxChoosableInteger >= desiredTotal) return true; //如果全部的和 小於 desiredTotal 則都是輸的 else if (maxChoosableInteger*(maxChoosableInteger + 1) >> 1 < desiredTotal) return false; unordered_map<int,bool> map; return Helper(maxChoosableInteger, desiredTotal, 0, map); } int main() { int a, b; cin >> a >> b; cout << canIWin(a, b); system("pause"); return 0; }

leetcode——464. 我能贏嗎