剑指offer之面试题14.剪绳子

题目链接
参考详解
首先先用贪心算法。
当n>=5时,我们要尽可能的多剪长度为3的绳子.
证明此结论可看:结论证明

class Solution {
public:
    int cuttingRope(int n) {
        if(n==2)return 1;
        if(n==3)return 2;
        if(n==4)return 4;//n=1,2,3,4单独讨论
        int a=n/3,b=n%3;
        if(b==0)return pow(3,a);//当余数为0时,直接求3的a次方
        else if(b==1)return pow(3,a-1)*4;
        //当余数为1时,直接求3的a-1次方,剩下的1和剩下的3相加变为4。不加的话,1就没有对乘积结果有贡献。
        else return pow(3,a)*2;
        //当余数为2时,有两种情况。(1)将两个3变为4.(2)直接乘2。自己在纸上举例证明会发现,直接乘2较大。
    }
};

再用动态规划方法:
定义函数:f(n)为长度是i的绳子剪段后各段长度成绩的最大值。
随便剪一刀有 n-1 种可能,每次前半段的长度i分别为 1,2,3,…,n-1。所以可得到递推公式:f(n)=max(f(i)*f(n-i))(0<i<n)。
可以采取从下往上的顺序计算,减少大量不必要的重复计算,即先算f(2)、f(3),再算f(4)、f(5),一直到f(n)。

class Solution {
public:
    int cuttingRope(int n) {
        if(n==2)return 1;
        if(n==3)return 2;
        int *product=new int[n+1];
        product[0]=0;product[1]=1;product[2]=2;product[3]=3;//当n>=4时
        int max=0;
        for(int i=4;i<=n;i++)
        {
            max=0;
            for(int j=1;j<=i/2;j++)
            {
                if(max < product[j] * product[i-j])
                {
                    max=product[j] * product[i-j];
                }
                product[i]=max;
            }
        }
        max=product[n];
        return max;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值