剑指Offer打卡day9—— AcWing 25. 剪绳子

【题目描述】
在这里插入图片描述
AcWing 25. 剪绳子

DFS

TLE了 只过了 8/11

class Solution {
    int ans = 0;
    //t 当前枚举到了第几段  m 表示总段数  n表示绳子剩余长度  res 乘积
    public void dfs(int t, int m, int n, int res){
        if( n < 0 || t > m) return;
        //System.out.println(t +" "+ m +" "+n +" "+ res);
        if( t ==  m){//段数符合
            if(n == 0 && res > ans) ans = res;
            return;
        }
        //枚举每一段的可能长度
        for(int x = 2; x <= n/ (m - t) + 1; x ++)
            dfs(t + 1, m, n - x, res * x);
        
    }
    
    public int maxProductAfterCutting(int length)
    {
        
        //枚举段数m[2, length - 1]  dfs(0, 2, length, 1);
        for(int m = 2; m < length ; m ++){
            //段数m确定了,要保证其m个段乘积最大 其最大可枚举的段长度也就确定了 为 n / m + 1
            dfs(0, m, length, 1);
        }
        return ans;
        
    }
}

【思路】
贪心选择

将一个大整数N分解成n1, n2, n3 , …… ni ,要使得其乘积最大,则:
ni < 5,数字2的个数不超过2,余下的全是3。
证明:
1、如果 ni > 5, (ni - 3)*3 = 3 * ni - 9 > ni 所以如果有ni > 5,那么一定可以拆成包含3的形式
2、如果 ni == 4,那么可以拆成两个2
3、ni 不为1 且 ni>=2
4、如果有三个以上的2,那么 3×3>2×2×2,所以替换成3乘积更大;



class Solution {
    public int maxProductAfterCutting(int n)
    {   //特判 要求段数是大于2的
        if( n <= 3) return (n - 1);
        int res = 1;
        // 4  7 10
        if(n % 3 == 1){//可以拆成两个2
            n -= 4;
            res *= 4;
        }else if(n % 3 == 2){//拆一个2
            n -= 2;
            res *= 2;
        }
        while(n > 0){
            n -= 3;
            res *= 3;
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值