package com.cloud.algorithm.demo;
import org.junit.Test;
/**
* DATE: 2021/4/9
* Author: xiaoqu
* Version: 1.0.0
* 动态规划 贪婪算法
*/
public class Topic14 {
/**
* 剪绳子
* 给你一根长度为n的绳子,请把绳子剪成m段(m,n都是整数,n>1并且m>1),
* 每段绳子的长度记成k[0],k[1],k[2]......k[m]。请问k[0]xk[1]x....xk[m]
* 可能的最大乘积是多少?例如,当绳子的长度为8时,我们把它剪成长度分别为2,3,3
* 的三段,此时得到的最大乘积是18
*/
@Test
public void topic14_1() {
int i = this.demo01(9);
int j = this.demo02(9);
System.out.println(i+":"+j);
}
/**
* 算法1
* 动态规划
* 减第一刀的时候有n-1种剪发,第一段可以试1,2,3,4.。。。。n-1
* 因此最大乘积是f(n)=max(f(i)*f(n-i))
*
*
* @return
*/
private int demo01(int n) {
int retInt = 0;
//因为必须剪一刀,所以是如下结果
switch (n) {
case 1:
retInt = 0;
break;
case 2:
retInt = 1;
break;
case 3:
retInt = 2;
break;
default:
retInt = 0;
}
if (n > 4) {
int[] maxArr = new int[n + 1];
maxArr[0] = 0;
maxArr[1] = 1;
maxArr[2] = 2;
maxArr[3] = 3;
for (int i = 4; i <= n; i++) {
int max = 0;
for (int j = 0; j <= i / 2; j++) { // i/2 长度取一半就可以了,另一半是重复的
int result = maxArr[j] * maxArr[i - j];
max = max > result ? max : result;
}
maxArr[i] = max;
}
retInt = maxArr[n];
}
return retInt;
}
/**
* 贪婪算法 当n>=5尽可能地多减为3的绳子,当剩下的为4时,减为2的绳子
* @param n
* @return
*/
public int demo02(int n){
int retInt = 0;
//因为必须剪一刀,所以是如下结果
switch (n) {
case 1:
retInt = 0;
break;
case 2:
retInt = 1;
break;
case 3:
retInt = 2;
break;
default:
retInt = 0;
}
if(n>3){
int num3=n/3;
//当绳子最后为4时,应该分成2X2 不应该是1X3
if(n-num3*3==1){
num3-=1;
}
int num2=(n-num3*3)/2;
retInt = (int) (Math.pow(2, num2) * Math.pow(3, num3));
}
return retInt;
}
}
剑指offer 面试题14 剪绳子 动态规划 贪婪算法
最新推荐文章于 2022-06-08 20:10:10 发布