剪绳子算法题

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

例1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1

例2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36

解法1: 这个解法是力扣大佬讲的数论解法,非常简单,在这里记录下来。

数论:任何大于1的数都可由2和3相加组成(根据奇偶证明)
           因为 2 x 2=1 x 4,2 x 3>1 x 5, 所以将数字拆成2和3,能得到的积最大
           因为2 x 2 x 2<3 x 3, 所以3越多积越大

思路:对于<=3的数,它的积等于n-1;对于>3的一个数,我们尽可能多给它找3,如果此时这个数等于2,那么我们给积乘以2,如果不等于2,就给积乘上当前剩的数。

 var cuttingRope = function(n){
           if(n<=3){
               return n-1;
           }
           var div=Math.floor(n/3);//div记录n可以找到3的个数
           var rem=n%3;//rem记录n找到最多3之后还剩多少
           var result=1;//记录积
           for(var i=0;i<div;i++){
           //如果当前i<能找到3的最多个数-1时,给积直接乘以3,到了最后一次,如果rem==2,就给积乘以(3*rem),否则乘以(3+rem)
               result*=i<div-1?3:(rem==2?3*rem:(3+rem));
                if(result>=1000000007){
              result=result%1000000007;
           }
           }
           return result;
       }

解法2: 采用动态规划的思想。

思路:
当n<=3时。直接返回n-1.
当n>=4时,从这里进行动态规划,我们设一个dp[i]来存放在绳子长为i,剪后积最大的值,
dp[1]=1,表示绳子长为1,只有不剪,积最大,为1
dp[2]=2,表示绳子长为2,在剪和不剪的比较下,只有不剪,积最大,为2
dp[3]=3,表示绳子长为3,在剪和不剪的比较下,只有不剪,积最大,为3
注:这里的dp[1],dp[2],dp[3]是在n>=4的时候定义的,不要把dp[1],dp[2],dp[3]返回当做n=2,n=3的结果。
接着我们从i=4到n一直找,把所有积最大的结果存放到dp[]里边,以绳子长为n为例:它可以从第1m处,第2米处…第n-1米剪,考虑到在第1m处剪和第n-1处剪,效果一样,我们只需剪到n/2处就可以了。定义一个maxValue,让它代表绳子长为n米时,积最大的结果,再定义j从1开始到n/2结束,表示可以剪的位置,maxValue=max(maxValue,dp[j]*dp[i-j]),在位置j 判断此处剪,积最大还是不剪及最大,遍历完j把当前maxValue赋值给dp[i].

 var cuttingRope = function(n){
           if(n<4){
               return n-1;
           }
           var dp=new Array();
           dp[1]=1;
           dp[2]=2;
           dp[3]=3;
           for(var i=4;i<=n;i++){
               var maxValue=0;
               for(var j=1;j<=i/2;j++){
                   maxValue=Math.max(maxValue,dp[j]*dp[i-j]);
               }
               dp[i]=maxValue;
           }
           return dp[n];
     }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值