leetcode——464. 我能赢吗
Posted 何许
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode——464. 我能赢吗相关的知识,希望对你有一定的参考价值。
参考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. 我能赢吗的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 961. 在长度 2N 的数组中找出重复 N 次的元素 / 464. 我能赢吗(博弈) / 675. 为高尔夫比赛砍树