算法与数据结构——打表法(找规律)(Java)

打表法

没什么高尚的
基本思路就是通过暴力解法看答案有什么规律

image-20220710153232227

奇数返回-1

涉及一点贪心的策略

先尽量使用装八个的袋子,看最多装到几个,不行就退,直到余数能刚好满足6的倍数,若装八个的袋子减到剩下0,就返回-1

优化:当余数大于24(6和8的最小公倍数)时就可以停止,后续的尝试没有意义了

public int minBags(int apple){
    if(apple<0||apple%2==1){
        return -1;
    }
    int bag6=-1;
    int bag8=apple/8;
    int rest=apple-8*bag8;
    while(bag8>=0&&rest<24){
        int resUse6=minBagBase6(rest);
        if(restUse6!=-1){
            bag6=restUse6;
            break;
        }
        rest=apple-8*(--bag8);
    }
    return bag6==-1?-1:bag6+bag8;
}

public int minBagBase6(int rest){
    return rest&6==0?(rest/6):-1;
}

打表

如果一个题目输入的是一个整数n,输出的也是一个整数n

在写出暴力解法的时候遍历答案,找规律

以此优化代码

注:但不是所有题目都是能这么优化

image-20220710155916130

在18之后每8个数有规律:

3 -1 3 -1 3 -1 3 -1

4 -1 4 -1 4 -1 4 -1

不用去关心为什么是这个规律

public int minBagAwesome(int apple){
    if((apple&1)!=0){
        return -1;
    }
    if(apple<18){
        return apple==0?0:(apple==6||apple==8)?1:(apple==12||apple==14||apple==16)?2:-1;
    }
    return (apple-18)/8+3;
}

吃草问题

n份青草放在一堆,先手和后手都绝对聪明,每次吃一份,每份青草分别是40,41,42…4n-1

看谁最后吃得多,返回吃得多的

public String winner1(int n){
    //0  1  2  3  4
    //后 先 后 先  先
    if(n<5){
        return (n==0||n==2)?"后手":"先手";
    }
    //n>=5时
    int base=1;//先手决定要吃的草 4^0
    while(base<=n){
        //当前一个n份草,先手吃掉的是base份,n-base是留给后手的草
        //母过程 先手 在子过程里是 后手
        if(winner1(n-base).equals("后手")){//子过程的后手赢就代表母过程的先手赢
            return "先手";//只要有一种方式能让我先手赢就可以了
        }
        if(base>n/4){//防止base*4之后溢出  注意这里写成n/4
            break;
        }
        base*=4;
    }
    return "后手";
}

打表

image-20220710163550746

找到规律:一直重复 后先后先先

public String winner2(int n){
    if(n%5==0||n%5==2){
        return "后手";
    }else{
        return "先手";
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值