464. Can I Win(硬币找零)

来源:互联网 发布:酷狗mac版 编辑:程序博客网 时间:2024/06/03 18:25

464. Can I Win(硬币找零)

  • Can I Win硬币找零
    • 题目链接
    • 题目描述
    • 题目分析
      • 方法状态压缩动态规划
        • 算法描述
    • 参考代码

题目链接

https://leetcode.com/problems/can-i-win/description/

题目描述

In the “100 game,” two players take turns adding, to a running total, any integer from 1..10. The player who first causes the running total to reach or exceed 100 wins.

What if we change the game so that players cannot re-use integers?

For example, two players might take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total >= 100.

Given an integer maxChoosableInteger and another integer desiredTotal, determine if the first player to move can force a win, assuming both players play optimally.

You can always assume that maxChoosableInteger will not be larger than 20 and desiredTotal will not be larger than 300.

Example

Input:
maxChoosableInteger = 10
desiredTotal = 11

Output:
false

Explanation:
No matter which integer the first player choose, the first player will lose.
The first player can choose an integer from 1 up to 10.
If the first player choose 1, the second player can only choose integers from 2 up to 10.
The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal.
Same with other integers chosen by the first player, the second player will always win.

题目分析

这道题是一道典型的状态压缩动态规划题目。所给的问题是NP的,但数据规模较小,利用二进制表示状态,以及动态规划的思想,可以把阶乘的状态压缩为指数的状态。int类型有超过20位的长度,所以可以用一个int表示状态,选择某一个数即把对应位置为1
下面分析几种情况:
- 选择一个可选的数后即可达到或超过desiredTotal时,为必胜状态
- 当选择任意可选的数后均达到必胜状态(说明当前玩家不管选择哪一个数,下一个玩家都是必胜局面,即他必输无疑),为必输状态
- 当选择一个可选的数后,可以达到必输状态(当前玩家一定会选择这个状态,因为下一步他的对手是必输的,这就保证了他的胜利),为必胜状态(题中声明两个玩家每一步都做出最优选择,所以玩家一定会选择能获得胜利的数)

方法:状态压缩动态规划

算法描述

  1. 通过简单计算排除可以直接得到答案的情况:
    • desiredTotal <= 1:直接选择1即可获得胜利
    • 可选数字总和小于desiredTotal:没有人能获得胜利
    • 可选数字总和小于desiredTotalmaxChoosableInteger为奇数时可以获得胜利,否则不能
  2. 利用状态转移方程进行搜索,在搜索中记录状态的输赢情况(1表示必胜,-1表示必输),避免重复计算

参考代码

class Solution {private:    int max;    vector<int> f;public:    bool canIWin(int maxChoosableInteger, int desiredTotal) {        max = maxChoosableInteger;        f = vector<int>(1 << 20, 0);        if (desiredTotal <= 1)            return true;        int sum = maxChoosableInteger * (maxChoosableInteger + 1) / 2;        if (sum < desiredTotal)            return false;        else if (sum == desiredTotal)            return maxChoosableInteger % 2;        else            return dfs(desiredTotal, 0);    }    bool dfs(int total, int state) {        if (total <= 0)            return false;        else if (f[state] > 0)            return true;        else if (f[state] < 0)            return false;        else {            for (int i = 0; i < max; i++)                if (!(state & 1 << i) && !dfs(total - i - 1, state | 1 << i)) {                    f[state] = 1;                    return true;                }            f[state] = -1;            return false;        }    }};
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 快速提神醒脑的方法 提神醒脑的东西 上课提神醒脑的方法 熬夜提神醒脑的方法 提神醒脑的饮料 醒脑静多少钱一支 高中生提神醒脑的方法 提神醒脑的茶 学生提神醒脑的方法 提神醒脑的方法 开车提神醒脑的方法 醒脑静10ml多少钱一支 提神醒脑增强记忆力的茶 提神醒脑的食物 半夜脑梗 什么可以提神醒脑 喝什么茶提神醒脑 学生喝什么茶提神醒脑 吃什么可以提神醒脑 喝什么饮料提神醒脑 喝什么可以提神醒脑 什么东西能提神醒脑 醒茶 熟普洱醒茶 普洱醒茶 普洱茶如何醒茶 醒茶是什么意思 醒购商城 醒购 为什么醒购那么便宜 揭秘醒购 醒购商城是正品吗 醒购app是正品吗 醒购商城的东西是真的吗 醒购商城app是正品吗 醒酒 醒酒喝什么 醒酒汤 快速醒酒 怎么醒酒 醒酒药