面试题十四:剪绳子
- 动态规划特点
- 求一个问题的最优解
- 整体问题的最优解依赖各个子问题的最优解
- 大问题分解成若干个小问题,这些小问题之间还重叠着更小的问题、
- 从上向下分析,从下往上求解问题(通常使用数组存储小问题的最优解)
- 贪心算法:每一步可以做出一个贪婪的选择,基于这个选择能得到最优解
将一个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]; }
浪波激泥