标签:
题目:
1、解法一
可以从第一层开始枚举一直到第N层,然后计算如果电梯在第x层停的话所有乘客总共要爬多少层楼。这是最为直接的一个解法。程序代码就是两重循环,找到最小值,这个算法的时间复杂度O(N^2)。
2、解法二(优化)
假设电梯停在第 i 层楼,我们计算出所有乘客总共爬楼梯的层数是Y。如果有N1个乘客想去的楼层在第 i 层之下,有N2个乘客正好想去的楼层是第 i 层,有N3个乘客想去的楼层在第 i 层之上。这个时候,重点来了:如果电梯改停在i-1层,所有目的地在第i - 1层以下的乘客可以少爬1层,总共少爬N1层,所有在i层及以上的乘客要多爬一层,总共多爬N2+N3层,这时总共需要爬Y-N1+N2+N3。反之,如果电梯在i+1层停所有目的地在第 i 层以上的乘客可以少爬1层,总共少爬N3层,所有在 i 层及以下的乘客要多爬一层,总共多N1+N2层,这时总共需要爬Y+N1+N2-N3层。可见,当N1 > N2+N3 时,电梯在第i-1层楼停更好;当N1+N2 < N3 时,电梯在i+1层停更好。其他情况在第i层更好。如此一来,问题的解法就出来了,从第一层开始考察,计算各位乘客走的楼层的数目,然后根据N1,N2,N3之间的关系进行调整,知道找到最佳楼层,这样算法时间复杂度优化到了O(N)。
二、源代码
1 package com.java.lianxi; 2 3 import java.util.Scanner; 4 5 public class lianxi6 { 6 public static void main(String[] args){ 7 int N,num;//电梯层数,乘客要停的电梯数 8 Scanner in=new Scanner(System.in); 9 System.out.print("请输入楼层数:"); 10 N=in.nextInt(); 11 int array[]=new int[N+1]; 12 for(int i=2;i<=N;i++) 13 { 14 System.out.print("请输入去第"+i+"层的乘客数:"); 15 array[i]=in.nextInt(); 16 } 17 fangfa1(N,array); 18 fangfa2(N,array); 19 } 20 public static void fangfa1(int N,int array[])//枚举 21 { 22 int sum[]=new int[N+1];//停在某层的结果 23 for(int i=2;i<=N;i++)sum[i]=0; 24 for(int i=2;i<=N;i++) 25 { 26 for(int j=2;j<=N;j++) 27 { 28 int k=i>j?(i-j):(j-i); 29 sum[i]+=array[j]*k; 30 } 31 } 32 int min=sum[2],m=2; 33 for(int i=3;i<=N;i++) 34 { 35 if(sum[i]<min) 36 { 37 min=sum[i]; 38 m=i; 39 } 40 } 41 System.out.println("使用方法1得到的结果是:停在第"+m+"层,上下楼层数最小值"+min); 42 43 } 44 public static void fangfa2(int N,int array[])//优化 45 { 46 int N1=0,N2=0,N3=0,i,j,k; 47 int min=0,m=2,sum=0; 48 array[1]=0; 49 for(i=2;i<=N;i++) 50 sum+=array[i]; 51 for(i=2;i<=N;) 52 { 53 N1+=array[i-1]; 54 N2=array[i]; 55 N3=sum-N1-N2; 56 if(N1+N2<N3) 57 i++; 58 else 59 break; 60 } 61 for(j=2;j<=N;j++) 62 { 63 k=i>j?(i-j):(j-i); 64 min+=array[j]*k; 65 } 66 System.out.println("使用方法2得到的结果是:停在第"+i+"层,上下楼层数最小值"+min); 67 } 68 69 }
三、运行结果截图
四、心得体会
通过这次练习,我懂得了拿到一道题,首先要先想用最简单最直接的方法来实现,然后再想办法优化,提高算法效率。
软件工程课堂练习——N层电梯只停一层求乘客爬楼层数最少(基本方法+优化方法)
标签:
原文地址:http://www.cnblogs.com/maximumminimum/p/4438035.html