动态规划
- 常用场景:
- 求一个问题的最优解(通常是最大值或最小值),而且该问题能够分解成若干个子问题,并且子问题之间还有重叠的更小子问题,就可以考虑使用动态规划来解决。
- 特点1:求解(子)问题的最优解
- 特点2:整体问题的最优解是依赖各个子问题的最优解
- 特点3:将大问题分解成若干个小问题,这些小问题之间还有相互重叠更小的子问题
- 特点4:从上往下分析问题,从下往上求解问题
- 一般来说从解决最小问题开始,并把已经解决的子问题的最优解存储下来(置于一维或二维数组中),并把子问题的最优解组合起来逐步解决整体问题。
贪婪算法
- 应用贪婪算法时需要考虑贪婪选择的问题,即需要用数学方式来证明贪婪选择是正确的。
面试题14:剪绳子
-
题目描述
- 给你一根长度为n的绳子,请把绳子剪成m段(m、n都是整数且大于1),每段绳子的长度记为k[0],k[1],…,k[m].请问k[0] * k[1] * … *k[m]可能的最大乘积是多少?例如,当绳子的长度是8时,剪为3 3 2三段,此时得到最大乘积18.
-
解法一:动态规划
public static int maxProductAfterCutting(int length){
if(length<2)
return 0;
if(length==2)
return 1;
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;
}
public static int maxProductAfterCutting(int length){
if(length<2)
return 0;
if(length==2)
return 1;
if(length==3)
return 2;
int timeOf3 = length/3;
if(length-timeOf3*3==1){
timeOf3 -= 1;
}
int timeOf2 = (length-timeOf3*3)/2;
return (int)Math.pow(3,timeOf3)*(int)Math.pow(2,timeOf2);
}