剪绳子:(数学+动态规划+贪心)

原题链接
题目描述:
在这里插入图片描述

方法一:利用数学公式推导

根据题意,任意一段长为n绳子都可以细分为a段( n = n 1 + n 2 + n 3 + . . . + n a n=n_1+n_2+n_3+...+n_a n=n1+n2+n3+...+na);
要使 S = n 1 × n 2 × n 3 × . . . × n a S=n_1\times n_2\times n_3\times...\times n_a S=n1×n2×n3×...×na值最大,由下面式子:
n 1 + n 2 + n 3 + . . . + n a a > = n 1 n 2 n 3 . . . n a a \frac{n_1+n_2+n_3+...+n_a}{a}>=\sqrt[a]{n_1n_2n_3...n_a} an1+n2+n3+...+na>=an1n2n3...na
得出当且仅当 n 1 = n 2 = n 3 = . . . = n a n_1=n_2=n_3=...=n_a n1=n2=n3=...=na时等号才成立,意思就是当把长度为N的绳子细分成数段等长为 x 的绳子时,他们的乘积 S S S 取得最大值,且乘积值为 x a x^a xa

由此我们就将问题转化为求解每段绳子长度x为何值时, S S S才能取得最大值
要求 S = x a S=x^a S=xa的最大值,我们需要对式子稍微变换一下;
a = n x a=\frac{n}{x} a=xn,得: S = x n x S=x^{\frac{n}{x}} S=xxn对两边取 l n ln ln得: l n S = n x l n x lnS=\frac{n}{x}lnx lnS=xnlnx
两边同时对x求导,得 1 S S ′ = − n x 2 l n x + 1 x × n x = ( 1 − l n x ) × n x 2 \frac{1}{S}S'=-\frac{n}{x^2}lnx+\frac{1}{x}\times \frac{n}{x}=(1-lnx)\times \frac{n}{x^2} S1S=x2nlnx+x1×xn=(1lnx)×x2n
S ′ = 0 S'=0 S=0时, 1 − l n x = 0 1-lnx=0 1lnx=0,解得 x = e x=e x=e
S = { 大 于 0 , x ∈ ( 0 , e ) 小 于 0 , x ∈ ( e , + ∞ ) S=\begin{cases} 大于0, x\in(0 , e)\\ 小于0,x\in(e,+\infty)\\ \end{cases} S={0,x(0,e)0,x(e,+)
因为 x x x为正整数,当 S S S值为最大时, x x x的可能取值有2或者3;
x = 2 x=2 x=2时, S ( 2 ) = 2 n 2 S(2)=2^\frac{n}{2} S(2)=22n
x = 3 x=3 x=3时, S ( 3 ) = 3 n 3 S(3)=3^\frac{n}{3} S(3)=33n
上面两个等式右边式子同时取6次方,不难判断出 S ( 3 ) = 9 n > S ( 2 ) = 8 n ( n 是 正 整 数 ) S(3)=9^n>S(2)=8^n(n是正整数) S(3)=9n>S(2)=8n(n)
所以我们可以得出结论:
只有尽可能地将绳子等分为多段长度为3的绳子,它们长度的乘积 S S S才能取得最大
这种剪法可能有三种情况:
第一种:
n刚好能被3整除,则此时乘积 S = 3 a S=3^a S=3a
第二种:
n除以3之后,余下一段长度为1的绳子,此时我们应该分出一段长度为3的绳子与余下的长度为1的绳子重新拼接回来,拼接后的绳子长度为4,则
S = 3 a − 1 × 4 S=3^{a-1}\times4 S=3a1×4第三种:
n除以3之后,余下一段长度为2的绳子,则余下的绳子不必再剪,所有绳子的乘积为 S = 3 a × 2 S=3^a\times2 S=3a×2

以上内容参考原文
代码的实现如下:

/*
执行用时:0 ms
内存消耗:6 MB
*/
class Solution {
public:
    int cuttingRope(int n) {
        if(n<4)
            return n-1;
        else
        {
            int a=n/3;//记录倍数
            int b=n%3;//记录余数
            if(b==0)
                return pow(3,a);
            else if(b==1)
                return pow(3,a-1)*4;
            else
                return pow(3,a)*2;
        }
    }
};

方法二:动态规划法

//用时0ms,空间:5.9MB
class Solution {
public:
    int cuttingRope(int n) {
        int a[59] = { 0 };
        if (n < 4)
            return n - 1;
        for (int i = 1; i <= n; i++)
        {
            a[i] = i;//初始为原长
            for (int j = 1; j < i; j++)
                a[i] = max(a[i], a[i - j] * a[j]);//比较减j时,与不减时的乘积大小,保留最大值
        }
        return a[n];
    }
};

更多算法题解,更关注我个人微信公众号:艺千秋录
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艺千秋录

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值