前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >剑指offer_14_剪绳子

剑指offer_14_剪绳子

作者头像
用户6055494
发布2019-09-24 16:01:14
3550
发布2019-09-24 16:01:14
举报
文章被收录于专栏:AVAJ
描述:给你一根长度为n的绳子,请把绳子剪成m段(m和n均为正整数,且m>1,n>1),每段绳子的长度记为a1、a2、a3、a4....an 现要求a1*a2*a3*a4*...*an的乘积最大,例如当绳子n的长度为8时,我们把它分成2、3、3三段这样得到的乘积也是最大的乘积18。

动态规划:当绳子长度为n时,我们剪第一刀有n-1种可能,因为第一刀可以剪1米、2米、3米....n-1米。因此f(n) = max(f(i) * f(n - i)),其中0 < i < n。根据描述我们能写出如下代码:

代码语言:javascript
复制
public static int cut(int length) {
    if(length < 2) {
        return 0;
    }
    if(length == 2) {
        return 1;
    }
    if(length == 3) {
        return 2;
    }
    int[] storage = new int[length + 1];
    // 初始化、这四个存的不是最优解而是用于计算的参数
    storage[0] = 0;
    storage[1] = 1;
    storage[2] = 2;
    storage[3] = 3;
    // 定义一个变量来存储最大值
    int max = 0;
    // 从第四米开始storage存的是最优解
    for (int i = 4; i <= length; i++) {
        // 从小到大开始把每个子问题最优解存在数组里
        for (int j = 1; j <= i / 2; j++) {
            int multiply = storage[j] * storage[i - j];
            if (multiply > max) {
                max = multiply;
            }
        }
        storage[i] = max;
    }
    return storage[length];
}

贪心:如果我们按照下面这种策略来剪绳子,则得到的各段绳子的长度乘积最大:当n>=5时,我们尽可能的多剪长度为3的绳子,当剩下的绳子长度为4时,就把绳子剪成2段长为2的,比如长为7的绳子我们剪成3 * 2 * 2这样得到最大值为12。

代码语言:javascript
复制
public static int cut(int length) {
    if(length < 2) {
        return 0;
    }
    if(length == 2) {
        return 1;
    }
    if(length == 3) {
        return 2;
    }
    // 记录要剪成3m一段的段数
    int three = length / 3;
    // 余下1m说明要腾出来一段凑4m来剪两个2m
    if (length - three * 3 == 1) {
        // 腾出
        three--;
    }
    // 要剪成2m的段数
    int two = (length - three * 3) / 2;
    return (int)(Math.pow(3,three) * Math.pow(2,two));
}

如此看来贪心算法能很快得到答案,但是需要扎实的数学功底。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员面试鸭 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档