zoukankan      html  css  js  c++  java
  • 292_Nim Game

    292_Nim Game

    一、题目详情

      题目的意思是给定石头的数量n,双方每次只能拿1-3个石头,己方先手,问在给定n后,自己能不能获胜。

    二、解题方法

    第一种方法(Time Limit Exceeded)

      一开始拿到题目,我的第一想法是使用博弈树的思想解题,当节点状态是己方行动&&石子数量<=3获胜,当节点是对方行动&&石子数量<=3失败。因为双方都足够聪明,所以要在对手每一步取走1个,2个,3个石子都必须取胜。代码如下:
    class Solution {
        public boolean canWinNim(int n) {
            return canWinNimHelper(n,true);
        }
        //isSelf==true表示己方行动,false表示对手行动
        public boolean canWinNimHelper(int n,boolean isSelf){
            if(n<=3&&isSelf) return true;
            if(n<=3&&!isSelf) return false;
            if(isSelf)
                return canWinNimHelper(n-1,!isSelf)
                    || canWinNimHelper(n-2,!isSelf)
                    || canWinNimHelper(n-3,!isSelf);
            else
                return canWinNimHelper(n-1,!isSelf)
                    && canWinNimHelper(n-2,!isSelf)
                    && canWinNimHelper(n-3,!isSelf);
        }
    }
    

      不出意料这种方法Time Limit Exceeded.

    第二种方法(Memory Limit Exceeded)

      因为上面这种算法超时,我观察了一下该算法,可以使用动态规划的思想解决超时问题。算法具体为:现在求得是由n个石子是否能赢,则只要拿走1个棋子或者两个棋子或者三个棋子后,对方会输就行(己方和对方是一样的,dp[i]只表示现在行动的那方能不能赢)。所以就有: dp[i] = !(dp[i-1]&&dp[i-2]&&dp[i-3])
    class Solution {
        public boolean canWinNim(int n) {
            if(n<=3) return true;
            boolean[] dp = new boolean[n+1];
            dp[1] = true;dp[2]=true;dp[3]=true;
            for(int i=4;i<=n;i++){
                dp[i] = !(dp[i-1]&&dp[i-2]&&dp[i-3]);
            }
            return dp[n];
        }
    }
    

      这个我以为可以accept,但是题目给的数据太大,建立dp数组太耗空间,但是这里可以改进一下:因为dp时只需要i的i-1,i-2,i-3的值,所以可以只保留这三个,这样就解决了内存的问题。

    第三种方法(Accept)

      这种方法比较特殊。只要n不能被4整除自己就能赢。 解释:我们可以知道当n=1,2,3时我们可以赢,当n=4时我们会输。当n=5,6,7时,我们可以对应的拿掉1,2,3个石子让对方行动时只有4个棋子,我们就能赢。n=8时,我们会输。以此类推,只要n不能被4整除自己就能赢。
    class Solution {
        public boolean canWinNim(int n) {
            return !(n%4==0);
        } 
    }
  • 相关阅读:
    Begin Example with Override Encoded SOAP XML Serialization
    State Machine Terminology
    How to: Specify an Alternate Element Name for an XML Stream
    How to: Publish Metadata for a WCF Service.(What is the Metadata Exchange Endpoint purpose.)
    Beginning Guide With Controlling XML Serialization Using Attributes(XmlSerializaiton of Array)
    Workflow 4.0 Hosting Extensions
    What can we do in the CacheMetaData Method of Activity
    How and Why to use the System.servicemodel.MessageParameterAttribute in WCF
    How to: Begin Sample with Serialization and Deserialization an Object
    A Test WCF Service without anything of config.
  • 原文地址:https://www.cnblogs.com/Mrfanl/p/11695378.html
Copyright © 2011-2022 走看看