Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 100场比赛-卡尼温_Java_Algorithm_Game Theory - Fatal编程技术网

Java 100场比赛-卡尼温

Java 100场比赛-卡尼温,java,algorithm,game-theory,Java,Algorithm,Game Theory,问题: 两名玩家从一个共同的数字池中选择数字,以达到一个总和 达到/超过目标值的玩家获胜 问题是要找出玩家1是否能够在给定的总人数和总人数下实施获胜策略 我的方法: 假设两个玩家都从可用池中选择最佳数量。 所谓最优,我的意思是- 检查池中可用的最高数字是否>=剩余值。[是]=>返回可用的最高值 如果无法获胜,请在池中选择不能保证下一回合获胜的最高可用号码(RequiredToWin-HighestNumberInThePool) 我刚刚提出了一个解决方案并编写了代码。我在试着分析这是否是仪式?在

问题:

  • 两名玩家从一个共同的数字池中选择数字,以达到一个总和
  • 达到/超过目标值的玩家获胜
  • 问题是要找出玩家1是否能够在给定的总人数和总人数下实施获胜策略
  • 我的方法:

    假设两个玩家都从可用池中选择最佳数量。 所谓最优,我的意思是-

  • 检查池中可用的最高数字是否>=剩余值。[是]=>返回可用的最高值

  • 如果无法获胜,请在池中选择不能保证下一回合获胜的最高可用号码(
    RequiredToWin-HighestNumberInThePool

  • 我刚刚提出了一个解决方案并编写了代码。我在试着分析这是否是仪式?在时间和空间上都是最优的。还试图了解如何改进我的编码约定——全局变量和使用条件语句的方式。这是解决方案吗

    在这个示例中,我使用了从100到105的预期总和来显示输出中的最佳选择。参见玩家1从可用池中选择5[7,6,5,4,3,2,1]

    编辑这不是问题的解决方案。这种方法在案例{pool:[1-5],Total:12}中失败。函数说,玩家2总是赢,但是玩家1总是可以赢,如果他从3开始

    /* 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, if two players might take turns drawing from a common pool of numbers 
    of 1..15 without replacement until they reach a total >= 100. This problem is 
    to write a program that determines which player would win with ideal play. 
    
    Write a procedure, "Boolean canIWin(int maxChoosableInteger, int desiredTotal)", 
    which returns true if the first player to move can force a win with optimal play. 
    
    Your priority should be programmer efficiency; don't focus on minimizing 
    either space or time complexity. 
    */
    
        package Puzzles;
    
        import java.util.List;
        import java.util.ArrayList;
    
        public class The100Game{
            List<Integer> pool;
            int raceTo;
    
            The100Game(int poolMax, int finalSum){
                /*  If (finalSum > combined sum of all numbers). 
                 *  This is an impossible problem to solve  
                 */
                if(finalSum > ((poolMax*poolMax + poolMax)/2)){
                    throw new IllegalArgumentException("Expected sum cannot be achieved!");
                }
    
                raceTo = finalSum;
                pool = new ArrayList<Integer>();
                for(int i=0;i<poolMax;i++)
                    pool.add(i+1);
            }
    
            /*  Autoplay the game with optimal mooves   */
            boolean canIWin(){
                int turns = 0;
                while(raceTo>0){
                    turns++;
                    System.out.println("Player"+( (turns%2==0)?"2":"1" )+" ==> "+pickANumber()+"   == Remaining ["+raceTo+"]");
                }
                return (turns%2==1);
            }
    
            /*  Pick an Optimal number, so to win 
             *  or prevent he opponent from winning 
             */
            int pickANumber(){
                int leastMax = -1;
                int len = pool.size();
                for(int i=len-1;i>=0;i--){
                    int tmp = pool.get(i);
                    if(tmp>=raceTo){
                        /*  Winning Pick */
                        pool.remove(i);
                        raceTo -= tmp;
                        return tmp; 
                    }else{
                        if(leastMax > 0){
                            /*  Picking the highest number available in the pool might let the next player win. 
                             *  So picking a number < leastMax, if available - to gaurentee otherwise.  */
                            if(tmp < leastMax){
                                pool.remove(i);
                                raceTo -= tmp;
                                return tmp;
                            }else{
                                continue;
                            }
                        }   
    
                        if(i-1 >= 0) {
                            /*  We know, the highest number available in the pool is < raceTo (target sum)
                             *  Check in the pool 
                             *  if the sum of the highest number + nextHighest number >=  raceTo (target sum)
                             *      [True]  => Skip both the numbers and look for a number < the LeastMax 
                             *                   so the opposite player does not win.
                             *      [False] => The highest number in the pool is the best pick
                             */
                            if(tmp+pool.get(i-1) < raceTo){
                                pool.remove(i);
                                raceTo -= tmp;
                                return tmp;
                            }else{
                                leastMax = raceTo - tmp;
                                i--;
                                continue;
                            }
                        }else{
                            pool.remove(i);
                            raceTo -= tmp;
                            return tmp;
                        }
                    }
                }
    
                /*  The raceTo sum cannot be achieved in this turn.
                 *  There is no number available in the pool 
                 *  that can prevent a Win in the next turn. 
                 *  So we return the highest number availble in the pool.
                 */
                int tmp = pool.get(pool.size()-1);
                pool.remove(pool.size()-1);
                raceTo -= tmp;
                return tmp;
            }
    
            public static void main(String[] args){
                The100Game game = new The100Game(15, 105);
                System.out.println("\nPlayer-"+(game.canIWin()?"1":"2")+" wins!");
            }
        }
    

    如果数字是正整数并且可以恢复(并且在1到N的连续范围内),那么您的基本想法基本上是正确的,选择不保证对手在倒数第二步中获胜的最大数字将使总数等于N+1。那么不管对手做什么,你都能赢。因此,如果总目标和M可被N+1整除,那么玩家2可以获胜,方法是使和始终可被N+1整除,否则玩家1可以通过首先使和可被N+1整除并窃取玩家2的策略获胜。如果数字不是连续的和/或不能重复使用,那么问题似乎就更难解决了。

    您的问题是您使用的算法是否是最佳算法?@mdewitt我尝试评估了所有我能想到的案例。这是解决方案吗?还有其他的最佳方法吗?如果没有不重复使用数字的限制,你就不能先说“1”来赢得比赛吗?是的,如果没有“不重复使用”的限制,总共100个数字加上[1-15]中的数字,我想你最多可以在6圈(15x6=90)内赢得比赛。这不是最佳策略。顺便问一下,游泳池里会有什么数字?例如,它们总是连续的吗?等等,我想你可以重复使用这些数字。