牛客网 剪绳子 为什么可以用递归?

题目描述

给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],...,k[m]。请问k[1]x...xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

思考

在潜意识中,有这么一个小学或者初中数学题,给你一根长度一定的绳子,如果围成一个正方形,那么他的面积一定比围成长方形要大,最大的面积是围成圆形。

不知道为什么,看到这个题目想到了这个。

绳子分成的段数确定的时候,是不是要把各个段让他尽量平均呢,我们通过验证,发现确实是这样的,比如8分成2段,4*4比3*5是要大的,所以这个结论有了。

那么绳子到底分成几段合适呢? 我没有仔细考虑,直接枚举了分成的段数,从2、3、4、5....都分了试试,取最大值。

这样题目就通过了。

class Solution {
public:
    int cutRope(int number) {
       int ans=0;
       for (int i=2; i<=number/2; i++) {
           int p=number/i;
           int o=number%i;
           int s=1;
           for (int j=1; j<=o; j++){
               s=s*(p+1);
           }
           for (int j=1; j<=(i-o);j++){
               s=s*p;
           }
           ans=max(ans,s);
       }
       return ans;
    }
};

代码中: i枚举分成的段数,p代表每段的基本长度,o是余数,余数再直接加到每段上,有多少算多少,最后统计答案。

进一步思考

没想到那样就过了,但是我隐隐感觉到,分成的段数应该不用枚举也可以直接得出来,有一个规律或者结论在等着我发现,于是我机智的把通过了的代码在统计答案时同时把段数记录下来,发现确实分成的段数是极多的,什么叫极多,就是保证每一段的p都是2或者3.

再说仔细点儿,就是 这个题目的答案是尽可能多的3和不得已的2构成的。

18能被3整除,那么他最后的答案组成就是3 3 3 3 3 3

19不能被3整除,那么他最后的3有5个:3 3 3 3 3       剩下的4: 需要分成 2 2

    因为4不能再拆成3和1了,显然3*1比2*2小。

所以得出结论

当这个数分到剩4的时候,直接2*2

                     剩3的时候,直接返回3

                    剩2的时候,直接返回2 

所以说答案是把这个数n分成尽可能多的3,再凑最后的3种情况即可。

到这里,这个题目就可以随心所欲的写了,可以是递归,可以是循环结构。

 

递归版:

class Solution {
public:
    int cutRope(int number) {
        if (number==2) return 2;
        if (number==3) return 3;
        if (number==4) return 4;
        return 3*cutRope(number-3);
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值