題目描述
給你一根長度爲n的繩子,請把繩子剪成m段(m、n都是整數,n>1並且m>1),每段繩子的長度記爲k[0],k[1],…,k[m]。請問k[0]xk[1]x…xk[m]可能的最大乘積是多少?例如,當繩子的長度是8時,我們把它剪成長度分別爲2、3、3的三段,此時得到的最大乘積是18。
輸入描述
輸入一個數n,意義見題面。(2 <= n <= 60)
輸出描述
輸出答案。
性能要求
時間限制:1秒 空間限制:65536K
題目分析
直接看題目是沒有頭緒,因而我們只有先一一列舉幾個,來查看是否有規律可循。
繩子長度n | 最大乘積 | 段數m | 公式 |
---|---|---|---|
2 | 1 | 2 | 1*1 |
3 | 2 | 2 | 2*1 |
4 | 4 | 2 | 2*2 |
5 | 6 | 2 | 3*2 |
6 | 9 | 2 | 3*3 |
7 | 12 | 3 | 3*4 |
8 | 18 | 3 | 3* 3*2 |
9 | 27 | 3 | 3* 3* 3 |
10 | 36 | 3 | 3* 3* 4 |
11 | 54 | 4 | 3* 3* 3* 2 |
12 | 81 | 4 | 3* 3* 3* 3 |
… | … | … | … |
由上表我們可以推斷出,當繩子長度超過4後,要使得分段後每段長度乘積最大,需要滿足公式爲 3*m + x = n (m > 1 並且 m < n, x 屬於 {2,3,4})。
因此根據該公式,我們在分段時,每次在總長度中減去3,直到剩下的那段長度x屬於{2,3,4}。現在使用代碼進行實現。
java實現
使用循環來得到結果
public class Solution {
public int cutRope(int target) {
if(target == 2){
return 1;
}else if(target == 3){
return 2;
}else if(target == 4){
return 4;
}
int result = 1;
while(target > 4 ){
result = result * 3;
target = target - 3;
}
return result * target;
}
}
使用遞歸實現
public class Solution {
public int cutRope(int target) {
if(target == 2){
return 1;
}else if(target == 3){
return 2;
}else if(target == 4){
return 4;
}
return process(target);
}
private int process(int target){
if(target <= 4){
return target;
}else {
return 3*process(target - 3);
}
}
}
使用上面兩種方式,也是我能夠想到的,它們都能達到性能要求,完成該題。但這不是最優算法。下面我貼出大佬們的解題思路。
優解
繩子長度n | 最大乘積 | 段數m | 公式 |
---|---|---|---|
2 | 1 | 2 | 1*1 |
3 | 2 | 2 | 2*1 |
4 | 4 | 2 | 2*2 |
5 | 6 | 2 | 3*2 |
6 | 9 | 2 | 3*3 |
7 | 12 | 3 | 3* 2*2 |
8 | 18 | 3 | 3* 3* 2 |
9 | 27 | 3 | 3* 3* 3 |
10 | 36 | 3 | 3* 3* 2*2 |
11 | 54 | 4 | 3* 3* 3* 2 |
12 | 81 | 4 | 3* 3* 3* 3 |
… | … | … | … |
由此推導出的公式爲
當 n % 3 =1 時,最大乘積 = 3^k * 2 * 2,k = n / 3 -1;
當 n % 3 = 2時,最大乘積 = 3^k * 2, k = n / 3;
相應的java代碼如下
public class Solution {
public int cutRope(int target) {
if (n == 2) return 1;
if (n == 3) return 2;
if (n % 3 == 1) {
int k = n / 3 - 1;
return (int)Math.pow(3, k) * 2 * 2;
}
if (n % 3 == 2) {
int k = n / 3;
return (int)Math.pow(3, k) * 2;
}
return (int)Math.pow(3, n / 3);
}
}
總結
方式一和方式二的差距是很大的。方式一僅僅是模擬出了規律,而方式二已經將這規律抽象爲數學模型,思維的高度上了整整一個層次。我還需要多培養這方面的能力。