剑指Offer——剪绳子
剪绳子
https://www.nowcoder.com/practice/57d85990ba5b440ab888fc72b0751bf8?tpId=13&&tqId=33257&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
题目描述
给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],...,k[m]。请问k[1]x...xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
输入描述:
输入一个数n,意义见题面。(2 <= n <= 60)
返回值描述:
输出答案。
示例
输入 8 返回值 18
题解
动态规划。用f(n)表示长度为n的绳子,最终的最大乘积。则
f(n)=max{1xf(n-1),2xf(n-2),...},f(n-1)=max{1xf(n-2),2xf(n-3),...}...,可以看出有重复的数据。因此可以采用记忆型动态规划。
public class Solution { public int cutRope(int target) { int[]res=new int[target+1]; res[2]=1;// 长度为2的绳子必须割为1、1. for(int len=3;len<=target;++len){ int max=0; for(int cut=1;cut<=len/2;++cut){ // 当前绳子已经被割过了,即满足m>1。因此剩下的绳子可以选择割或者不割。 int temp_1=res[cut]>cut?res[cut]:cut; int temp_2=res[len-cut]>len-cut?res[len-cut]:len-cut; int temp_max=temp_1*temp_2; max=max>temp_max?max:temp_max; } res[len]=max;// 当前绳子割的情况下的最大值 } return res[target]; } }