美文网首页
1025. 除数博弈

1025. 除数博弈

作者: 最困惑的时候就是能成长的时候 | 来源:发表于2020-05-24 12:36 被阅读0次

    题目地址

    1.想法

    1.1动态规划

    首先,可以确定选到1的人一定输,为了变成1,前一个人的必须是2,因为其他的数字没法造成1,为了变成2,那么前一个人的选择必须是3,同理推断
    next_value = now_value-k;
    now_value%k == 0;

    倒数第N步 赢方 输方
    1 1
    2 2
    3 3
    4 4/6
    5 5

    因为两个人都是极度聪明的,所以后一个的选择必须是惟一的且必须是一定输的,这样才能前一个人的选择是赢的。那么我们从底层推测,
    例:1.当前的数字为1的时候则一定输,
    2.对于前一个数字2来说,因为这两个人不会犯错,所以一定让下一个数字为1,则当前为2 的人一定赢。
    3.同理当前为3的人一定输
    4.所以当为4的时候可以变成3和2,则若为2则一定输,为3则一定赢,那么此时一定选择变成3,则一定赢。
    5.而对于5来说和4正好相反,因为多了一步,5只能改变成4,
    6.而对于6来说,可以变成5和4和3,选择中5,3必输,4必赢。

    那么就是说子选项中存在一个必赢的选择,则一定赢,否则一定输

    那么我们定义F[n] = 必赢(true) ,存在(n-i)使得n%i==0且F[n-i] =必输(false)
    归纳公式为:
    f(n)\begin{cases}1.true ,&∃(n-i),n\%i==0\&\&f(n-i)=false\\2.false,& 否则.\end{cases}

    1.1代码

    class Solution {
       public boolean divisorGame(int N) {
            boolean[] result = new boolean[N+1];
            result[1] = false;
            for(int i=2;i<N+1;i++){
                int temp = (int) Math.pow(i,((double)1)/2);
                boolean flag = false;
                for(int j = 1;j<=temp;j++){
                    if(i%j==0&&!result[i-j]){
                        flag = true;
                    }
                }
                result[i] = flag;
            }
            return result[N];
        }
    }
    

    1.2总结法

    奇数的约数也是奇数,奇数减奇数就是偶数,那么偶数在不考虑时间的情况下每次都-1,另一个人得到的一定是奇数,那么拿到奇数的人无论怎么处理返回给上一个人的一定是偶数,那么拿到偶数的人一定是胜利的,因为一定拿到2,而拿到奇数的人一定是失败的因为手上一定是1。

    1.2代码

    class Solution {
       public boolean divisorGame(int N) {
            return N%2 == 0;
        }
    }
    

    相关文章

      网友评论

          本文标题:1025. 除数博弈

          本文链接:https://www.haomeiwen.com/subject/zybdahtx.html