zoukankan      html  css  js  c++  java
  • 【剑指Offer-动态规划和贪婪算法】剪绳子

    问题描述

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

    思路1

    设f(n)为将长为n的绳子剪为m段后成绩的最大值,则f(n)=max(f(i)*f(n-1)) (n>3, 0<i<n),其中的边界值为f(1)=0,f(2)=1,f(3)=2。代码如下:

    class Solution {
    public:
        int cutRope(int number) {
            if(number<2)
                return 0;
            if(number==2)
                return 1;
            if(number==3)
                return 2;
    
            int ans[number+1];
            ans[1] = 0;
            ans[2] = 2;
            ans[3] = 3;
            for(int i=4; i<=number; i++){
                int max = -1;
                for(int j=1; j<=i/2; j++){
                    if(max<ans[j]*ans[i-j])
                        max = ans[j]*ans[i-j];
                    
                    ans[i] = max;
                }
                
            }
            return ans[number];
        }
    };
    

    这个要注意边界值,也就是不是所有的n对应的f(n)都满足f(n)=max(f(i)*f(n-1)),只有当n>3时才满足。

    思路2

    思路1的时间复杂度为O(n2),可以使用贪心算法将时间复杂度降为O(1)。
    当n≥5时,有3(n-3)≥2(n-2)>n, 所以我们应该尽可能的多剪成长度为3的绳子段;当n=4时,因为2×2>3×1,所以应该剪成两段长度为2的绳子;当n<4时是边界条件,直接返回即可。代码如下:

    class Solution {
    public:
        int cutRope(int number) {
            if(number<2)
                return 0;
            if(number==2)
                return 1;
            if(number==3)
                return 2;
            
            int len3Num = number / 3;
            if(number-3*len3Num==1)
                len3Num--;
            int len2Num = (number-3*len3Num) / 2;
            return (int)(pow(3, len3Num)) * (int)(pow(2, len2Num));
        }
    };
    

    总结

    动态规划的4个特点:

    • 动态规划用来求一个问题的最优解;
    • 整体问题的最优解依赖于各个子问题的最优解;
    • 可以把大问题分解成若干小问题,这些小问题之间还有相互重叠的更小的子问题;
    • 从上往下分析问题,从下往上求解问题并存储。
  • 相关阅读:
    修复 Visual Studio Error “No exports were found that match the constraint”
    RabbitMQ Config
    Entity Framework Extended Library
    Navisworks API 简单二次开发 (自定义工具条)
    NavisWorks Api 简单使用与Gantt
    SQL SERVER 竖表变成横表
    SQL SERVER 多数据导入
    Devexpress GridControl.Export
    mongo DB for C#
    Devexress XPO xpPageSelector 使用
  • 原文地址:https://www.cnblogs.com/flix/p/12405386.html
Copyright © 2011-2022 走看看