剑指Offer14-剪绳子1&2

题目描述–剪绳子1

在这里插入图片描述

思路分析

首先要分析出怎么切分是最优方案,显然和一定时,分成相等的数的乘积最大。用简单的数学归纳的思想可以发现,4对应2*2,5对应2x3,6对应3x3,7对应3x2x2,8对应3x3x2,显然分为3是最优选,然后是2。
由不等式也可解出极值点是e约为2.7,距离3最近。
在这里插入图片描述

动态规划

首先最直接会想到用动态规划的思想解题,先考虑切3,判断切3后的值是否大于dp中对应的值,依此向前填充dp矩阵,然后考虑切2

int cuttingRope(int n) {
        if(n < 4){
            return n - 1;
        }
        vector<int> resMat(n + 1);
        resMat[2] = 1;
        resMat[3] = 2;
        //优先切出3最好,2次之,动态规划只需要考虑后面多切的一刀
        for(int i = 4; i < n + 1; ++i){
            if(i - 3 > resMat[i - 3]){
                resMat[i] = 3 * (i - 3);
            }
            else{
                resMat[i] = 3 * resMat[i - 3];
            }
            if(i - 2 > resMat[i - 2]){
                resMat[i] = max(resMat[i], 2 * (i - 2));
            }
            else{
                resMat[i] = max(resMat[i], 2 * resMat[i - 2]);
            }
        }
        return resMat[n];
    }

贪心思想

很简单,既然3最好就尽量多的切为3,判断n%3的值,为0,结果为3(n/3),为1,结果为4x3((n-4)/3),为2,结果为2x3^((n-2)/3)

    int cuttingRope(int n) {
        if(n < 4){
            return n - 1;
        }
        //贪心算法,优先剪3
        int res;
        if(n % 3 == 0){
            res = int(pow(3, n / 3));
        }
        else if(n % 3 == 2){
            res = 2 * int(pow(3, (n - 2) / 3));
        }
        else if(n % 3 == 1){
            res = 4 * int(pow(3, (n - 4) / 3));
        }
        return res;
    }

题目描述–剪绳子2

在这里插入图片描述

思路分析

题目仅是将n的范围扩大了,这样显然带来了大数越界的问题,显然不能再用动态规划的思想求解,只能选择贪心算法,此题也就变成了一个快速幂求余的问题。

代码

    int cuttingRope(int n) {
        if(n < 4){
            return n - 1;
        }
        const int modNumber = 1000000007;
        //贪心,快速幂求余
        long res;
        if(n % 3 == 1){
            res = 4 * quickM(3, int((n - 4) / 3)) % modNumber;
        }
        else if(n % 3 == 2){
            res = 2 * quickM(3, int((n - 2) / 3)) % modNumber;
        }
        else{
            res = quickM(3, int(n / 3));
        }
        return res;
    }
    //快速幂
    long quickM(long base, int N){
        long res = 1;
        while(N > 0){
            if(N & 1){
                res *= base;
                res %= 1000000007;
            }
            base *= base;
            base %= 1000000007;
            N >>= 1;
        }
        return res;
    }

个人博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值