您的位置:首页 > 其它

如何切出最大长度乘积 Maximum Product Cutting @geeksforgeeks

2014-01-30 14:42 579 查看
转自出处

Given a rope of length n meters, cut the rope in different parts of integer lengths in a way that maximizes product of lengths of all parts. You must make at least one cut. Assume that the length of rope is more than 2 meters.

Examples:
Input: n = 2
Output: 1 (Maximum obtainable product is 1*1)

Input: n = 3
Output: 2 (Maximum obtainable product is 1*2)

Input: n = 4
Output: 4 (Maximum obtainable product is 2*2)

Input: n = 5
Output: 6 (Maximum obtainable product is 2*3)

Input: n = 10
Output: 36 (Maximum obtainable product is 3*3*4)


1) Optimal Substructure:

This problem is similar to Rod Cutting Problem. We can get the maximum product by making a
cut at different positions and comparing the values obtained after a cut. We can recursively call the same function for a piece obtained after a cut.

Let maxProd(n) be the maximum product for a rope of length n. maxProd(n) can be written as following.

maxProd(n) = max(i*(n-i), maxProdRec(n-i)*i) for all i in {1, 2, 3 .. n}

2) Overlapping Subproblems

Following is simple recursive C++ implementation of the problem. The implementation simply follows the recursive structure mentioned above.

A Tricky Solution:

If we see some examples of this problems, we can easily observe following pattern.

The maximum product can be obtained be repeatedly cutting parts of size 3 while size is greater than 4, keeping the last part as size of 2 or 3 or 4. For example, n = 10, the maximum product is obtained by 3, 3, 4. For n
= 11, the maximum product is obtained by 3, 3, 3, 2. Following is C++ implementation of this approach.

[java] view
plaincopy





package DP;

public class MaxProductCutting {

public static void main(String[] args) {

System.out.println(maxProdRec(10));

System.out.println(maxProdDP(10));

System.out.println(maxProdTrick(10));

}

public static int maxProdRec(int n){

if(n==0 || n==1){

return 0;

}

int max = 0;

for(int i=1; i<n; i++){

// 1.只切一刀 2.切完一刀后,把余下的继续切

int bigger = Math.max(i*(n-i), i*maxProdRec(n-i));

max = Math.max(max, bigger);

}

return max;

}

// Time: O(n^2), space:O(n)

public static int maxProdDP(int n){

// maxProd[i]: 总长度为i的绳子能切出的最大乘积

int[] maxProd = new int[n+1];

maxProd[0] = maxProd[1] = 0;

// Build the table maxProd[] in bottom up manner and return

// the last entry from the table

for(int i=1; i<=n; i++){ // 总长度为i

int max = 0;

for(int j=1; j<=i/2; j++){ // 切长度为j

int bigger = Math.max(j*(i-j), j*maxProd[i-j]);

max = Math.max(max, bigger);

}

maxProd[i] = max;

}

return maxProd
;

}

// 规律:不断以3为单位长度切

public static int maxProdTrick(int n){

if(n==2 || n==3){ // n equals to 2 or 3 must be handled explicitly

return n-1;

}

int res = 1;

while(n > 4){ // Keep removing parts of size 3 while n is greater than 4

n -= 3;

res *= 3; // Keep multiplying 3 to res

}

return n*res; // The last part multiplied by previous parts

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: