ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

算法和数据操作-动态规划与贪婪算法

2021-02-26 19:04:36  阅读:239  来源: 互联网

标签:int 绳子 length 问题 算法 贪婪 长度 最优 动态


动态规划是热门话题,如果一个面试题就问题的最优解,通常是最大值和最小值,而且能分解成若干个子问题,子问题也能分解更小的子问题,就能考虑动态规划

线分析要能否把大问题分解成小问题,小问题存在最优解,然后把小问题组合起来能够得到整个问题的最优解,用动态规划

为了避免重复求子问题,可以用从下往上的顺序计算子问题的最优解并存储下来,以此为基础球的最大问题的最优解,从上往下分析问题,从下往上求解问题

在用动态规划的时候,每一步都可能面临若干选择

动态规划四个特点:

1.求一个问题的最优解

2.整体问题的最优解依赖于各个子问题的最优解

3.大问题可以分解为若干个小问题,小问题之间还有更小的子问题

4.从上往下分析问题,从下往上求解问题

 

贪婪算法和动态规划算法不一样,应用贪婪算法的时候,每一步都可以做出一个贪婪选择,基于这个选择得到最优解

 

面试题14.剪绳子

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

 

常规时间O(n^2),空间O(n)-》动态规划

时间空间都为O(1)的贪婪算法

 

动态规划方法

定义f(n)为把长度为n的绳子剪成若干段后各段长度乘积的最大值

在剪第一刀的时候,我们有n-1种可能,也就时间出来的第一段绳子的可能长度为1,2,……n-1。因此f(n)=max(f(i)*f(n-1)),其中0<i<n

这是一个从上到下的递归公式,会有重复子问题,大量不必要的计算,更好的办法是从下到上

当绳子长度为2的时候,只能剪成长度都为1的两段,因此f(2)等于1,当绳子长度为3的时候,可能把绳子剪成长度分别为1和2的两端或者长度都为1的三段,由于1*2>1*1*1,因此f(3)=2

public static int maxProductAfterCutting_solution1(int length){
    if(length==1){
        return 0;
    }
    else if(length==2){
        return 1;
    }
    else if(length==3){
        return 2;
    }
    int[] products=new int[length+1];
    products[0]=0;
    products[1]=1;
    products[2]=2;
    products[3]=3;
    int max=0;
    for(int i=4;i<=length;i++){
        max=0;
        for(int j=1;j<=i/2;j++){
            int product=products[j]*products[i-j];
            if(max<product){
                max=product;
            }
            products[i]=max;
        }
    }
    max=products[length];
    return max;
}

 

贪婪算法

长度剩下5以上,尽可能多剪长度为3的绳子,长度为4的时候,尽量剪长度为2的绳子

public static int maxProductAfterCutting_solution2(int length){
    if(length<2){
        return 0;
    }
    else if(length==2){
        return 1;
    }
    else if(length==3){
        return 2;
    }
    int timesOf3=length/3;
    if(length-timesOf3*3==1){
        timesOf3=timesOf3-1;
    }
    int timesOf2=(length-timesOf3*3)/2;
    return (int)(pow(3,timesOf3))*(int)(pow(2,timesOf2));
}

在n>=5的时候,可以证明2(n-2)>n并且3(n-3)>n,当绳子长度大于等于5,我们把他剪成长度为3或者2的绳子段。另外当n>=5时,3(n-3)>=2(n-2)因此我们尽可能减去长度为3的段

当绳子长度为4的时候,剪一刀,2*2>3*1

标签:int,绳子,length,问题,算法,贪婪,长度,最优,动态
来源: https://www.cnblogs.com/ak918xp/p/14453654.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有