2021/4/6 剑指 Offer 14- I. 剪绳子

124 篇文章 1 订阅
53 篇文章 0 订阅


方法一:自下而上动态规划 + 记忆化:两个循环

class Solution {
public:
    int cuttingRope(int n) {
        if(n <= 3) return n - 1; // 当绳子的总长度<=3时,做特殊情况处理
        //长度<=3时 必须要剪 所以会小 但是一旦>3就不用动长度3以下的绳子了 
        vector<int> res(n + 1, 0); // res[i]表示长度为i的绳子剪成若干段之后,乘积的最大值
        // 特殊处理:如果某个长度的绳子,剪了一下之后,其中一段的长度在[0,3]的区间内,就不要再剪这一段了
        // 因为剪了之后,乘积会变小,而res[i]是长度为i的绳子剪成若干段后能获得的最大乘积
        // 所以[res[0],res[3]]要单独处理(如下)
        res[0] = 0;
        res[1] = 1;
        res[2] = 2;
        res[3] = 3;
        int maxProduct = 0;
        for(int i=4; i<=n; ++i)
        {
           // maxProduct = 0;
            for(int j=1; j<=i/2; ++j)//注意这里的范围
            {
                // 循环体中写i/2是为了减少计算次数(因为比如1x3和3x1值是一样的,计算一次即可)
                int temp = res[j] * res[i-j];//注意这里
                maxProduct = getMax(maxProduct, temp);
                res[i] = maxProduct; // res数组是做记忆化处理用的
            }  
        }
        return res[n];
    }
    int getMax(int a, int b)
    {
        return a >= b ? a : b;
    }
};

作者:superkakayong
链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof/solution/zi-jie-ti-ku-jian-14-i-zhong-deng-jian-sheng-zi-1s/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution {
public:
    int cuttingRope(int n) {
        if(n <= 3) return n - 1;
        int res = 0, count3 = n / 3;
        if(n % 3 == 0) return pow(3, count3);
        else if( n % 3 == 1)
        {
            count3 --;
            return pow(3, count3) * 4;
        }
        else return pow(3, count3) * 2;
    }
};

作者:superkakayong
链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof/solution/zi-jie-ti-ku-jian-14-i-zhong-deng-jian-sheng-zi-1s/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  1. 其实res数组求的是绳子长度大于等于3的时候的,因为代码的第一行就已经给出了绳子长度小于等于3时能剪出的最大长度了。所以res[3]应该等于3,原因是当绳子长度大于等3时(比如4),每当剪了一次之后,某一部分的长度在[0,3]之间,我们就不应该再剪这一部分了,因为剪了会使得这一部分的乘积变小(比如长度为3,不剪的话它就是3,剪了的话就是1*2=2,2<3,不划算)。
  2. 至于为啥 vector 中是 n+1 个元素,因为这样比较方便我们计算。设为 n+1 个元素的话,res[n] 表示的就是长度为 n的绳子能剪出的最大长度了,不然的话得是 res[n-1] 才能表示,就会有点乱。
    左神说在笔试中不会使用贪心算法 因为只要找到了贪心策略代码很简单 但是贪心策略很难找,所以没有看贪心的解法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值