动态规划
- 把大问题分解为小问题,每个小问题有最优解,用小问题的最优解可以组合为大问题的最优解。
- 适用情况:
- 最优解问题
- 整体问题的最优解依赖子问题的最优解
- 大问题分解为小问题,小问题还有相互重叠的更小的子问题
- 从上而下分析问题,从下往上求解问题
贪婪算法
- 每一步都可以做出一个贪婪的选择得到最优解
题目
长度为n的绳子切分为m段(至少要切一刀)使得每段长度的乘积最大(m,n均为整数),并且返回这个最大的乘积
- 第一种解法:动态规划(把切分为多段分解为切分为2段的问题)
- 分析:
- 切一刀分为两段(左和右)。
- 左右两段也是切一刀(左和右),乘积最大(大问题分解为小问题)。
- 最终的情况是长度为2的绳子切分为了两个长度为1的段,乘积f(2)=1。
- 切为两段的话:切分位置是在1到n-1,乘积为f(n)=f(i)*f(n-i)
代码实现
- 动态规划
public int maxOfShengzi(int length) {
if(length<2) {
return 0;
}
if(length==2) {
return 1;
}
if(length==3) {
return 2;
}
//小问题的最优解存放在数组中(把长度为i的绳子分为若干段之后乘积的最大值,不规定必须切一刀)
int[] bestSolution=new int[length+1];
bestSolution[0]=0;
bestSolution[1]=1;
bestSolution[2]=2;
bestSolution[3]=3;
int max=0;
//i表示的是绳子的长度,j表示的是切分位置(j=i/2的时候相当于后半段的0,即不切分)
for(int i=4;i<=length;i++) {
max=0;
for(int j=1;j<=i/2;j++) {
int chegnjis=bestSolution[j]*bestSolution[i-j];
if(chengjis>max) {
max=chengjis;//max表示的是最大的乘积
}
bestSolution[i]=best;//把小问题的最优解存放在最优解数组里面
}
}
max=bestSolution[length];
return max;
}
- 贪婪算法
尽可能多切3,剩下绳子长度为4时,切分为2*2.(至少切一刀)
3(n-3)>=2(n-2)
public static int maxOfShengzi(int length) {
if(length<2) {
return 0;
}
if(length==2) {
return 1;
}
if(length==3) {
return 2;
}
//尽可能多的剪为3的段
int timeOf3=length/3;
int timeOf2=0;
//绳子最后一段为4时,剪成2段2
if(length-timeOf3*3==1) {
timeOf3-=1;
timeOf2=(length-timeOf3*3)/2;
}
//最后一段为2,2的次数为1
else {
timeOf2=1;
}
return (int)(Math.pow(3,timeOf3))*(int)(Math.pow(2,timeOf2));
}