剪绳子

题目描述

给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[1],...,k[m]。请问k[1]x...xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

输入描述:

输入一个数n,意义见题面。(2 <= n <= 60)

输出描述:

输出答案。
示例1

输入

复制
8

输出

复制
18

法1:暴力递归破解法:
 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStreamReader;
 4 
 5 
 6 public class test {
 7     private static int back_track(int target){
 8         if(target<=4) return target;
 9 
10         int ret=0;
11         for(int i=1;i<=target;i++){
12             int t = back_track(target - i);
13             ret = i*t>ret?i*t:ret;
14         }
15         return ret;
16     }
17 
18     private static int cutRope(int target){
19         if(target==2) return 1;
20         else if(target==3) return 2;
21         return back_track(target);
22     }
23     public static void main(String[] args) throws IOException {
24         System.out.println("请输入绳子的长度:");
25         BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
26         int n=Integer.parseInt(br.readLine());
27         System.out.println(cutRope(n));
28     }
29 }

时间复杂度为O(n!),空间复杂度为O(n);相当于根结点为back_track(n)的一棵树,叶子结点都是back_track(1),树的深度是n,第二层从左到右的子树复杂度分别为O((n-1)!),O((n-2)!),...,最外面还有一层循环,所以是O(n!);


法2:记忆递归法:
 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStreamReader;
 4 
 5 
 6 public class test {
 7     private static int back_track(int target,int[] mark){
 8         if(target<=4) return target;
 9         if(mark[target]!=0) {
10             return mark[target];
11         }
12         int ret=0;
13         for(int i=1;i<=target;i++){
14             int t = back_track(target - i,mark);
15             ret = i*t>ret?i*t:ret;
16         }
17         return mark[target]=ret;
18     }
19 
20     private static int cutRope(int target){
21         if(target==2) return 1;
22         else if(target==3) return 2;
23         int[] mark=new int[target+1];
24         return back_track(target,mark);
25     }
26     public static void main(String[] args) throws IOException {
27         System.out.println("请输入绳子的长度:");
28         BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
29         int n=Integer.parseInt(br.readLine());
30         System.out.println(cutRope(n));
31     }
32 }

时间复杂度是O(n^2),空间复杂度是O(n);最外面循环一遍,然后每个mark[i]计算一次,共计算n次,所以O(n^2);



法3:动态规划求解:
 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStreamReader;
 4 
 5 public class pass {
 6     private static int cutRope(int target){
 7         if(target==2) return 1;
 8         else if(target==3) return 2;
 9         int[] f=new int[target+1];
10         for(int i=1;i<=4;i++){
11             f[i]=i;
12         }
13         for(int i=5;i<=target;i++){
14             for(int j=1;j<i;j++){
15                 f[i]=f[i]>j*f[i-j]?f[i]:j*f[i-j];
16             }
17         }
18         return f[target];
19     }
20     public static void main(String[] args) throws IOException {
21         System.out.println("请输入绳子的长度:");
22         BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
23         int n=Integer.parseInt(br.readLine());
24         System.out.println(cutRope(n));
25     }
26 }

时间复杂度是O(n^2),空间复杂度是O(n);

 

posted @ 2020-06-24 22:53  打屎也不熬夜  阅读(92)  评论(0编辑  收藏  举报