面试题十四:剪绳子

  •  动态规划特点
    • 求一个问题的最优解 
    • 整体问题的最优解依赖各个子问题的最优解
    • 大问题分解成若干个小问题,这些小问题之间还重叠着更小的问题、
    • 从上向下分析,从下往上求解问题(通常使用数组存储小问题的最优解)
  • 贪心算法:每一步可以做出一个贪婪的选择,基于这个选择能得到最优解

 

将一个n长的绳子剪成m段,每一段长度乘起来最大 ,m>1,n>1

 

方法一:贪心策略

        int maxPa(int length){
                    //再分割
                   if(length<2)  return 0;
                   if(length==2) return 1;
                   if(length==3) return 2;
                    
                   
                //尽可能多地剪去长度为3的绳子
                    int temp = length / 3;
                    //当绳子最后剩下长度为4的时候,不能再剪去长度为3的绳子段
                    //此时更好的方法是把绳子剪成长度为2的两段,因此2x2>3x1
                    if (length - temp * 3 == 1)
                    {
                        temp -= 1;
                    }
                    
                    int temp2 = (length - temp * 3) / 2;
                    return (int)(pow(3, temp))*(int)(pow(2, temp2));

            }

 方法二:动态规划  O(n^2)

        int maxPa(int length){
                    //因为至少剪一次
                   if(length<2)  return 0;
                   if(length==2) return 1;
                   if(length==3) return 2;
                    
                   int[] array=new int[length+1];    //数组中第n个元素表示长度n最优解
                   //作为不再切割的长度
                    array[0]=0; array[1]=1;array[2]=2; array[3]=3;
                    
                   //长度4以下切割的最优解·直接上面返回
                    for(int i=4;i<=length;++i)
                    {   
                        int  max=0;
                        //寻找最优长度,j<=i/2;避免重复计算
                        for(int j=1;j<=i/2;++j)
                        {
                            int pro=array[j] * array[ i-j];
                            if(max<pro)  max=pro;
                            array[i] = max;
                        }                   
                    }
                return array[length];
            }

 

posted @ 2020-03-29 14:31  浪波激泥  阅读(263)  评论(0编辑  收藏  举报