NYOJ---71解题报告,独木舟上的旅行

来源:互联网 发布:淘宝网创建时间 编辑:程序博客网 时间:2024/05/01 12:56

独木舟上的旅行

时间限制:3000 ms  |  内存限制:65535 KB
难度:2
描述

进行一次独木舟的旅行活动,独木舟可以在港口租到,并且之间没有区别。一条独木舟最多只能乘坐两个人,且乘客的总重量不能超过独木舟的最大承载量。我们要尽量减少这次活动中的花销,所以要找出可以安置所有旅客的最少的独木舟条数。现在请写一个程序,读入独木舟的最大承载量、旅客数目和每位旅客的重量。根据给出的规则,计算要安置所有旅客必须的最少的独木舟条数,并输出结果。

输入
第一行输入s,表示测试数据的组数;
每组数据的第一行包括两个整数w,n,80<=w<=200,1<=n<=300,w为一条独木舟的最大承载量,n为人数;
接下来的一组数据为每个人的重量(不能大于船的承载量);
输出
每组人数所需要的最少独木舟的条数。
样例输入
3
85 6
5 84 85 80 84 83
90 3
90 45 60
100 550 50 90 40 60
样例输出
5
3
3
上传者

这个题是在贪心算法里面的,其实贪心算法我也不太懂,但是看过一点点的介绍。求解一个具体的问题时候,可以将这个问题划分成多个子问题,对每一个子问题求解其最优解,整合起来就可以认为求得了这个问题的最优解,因为最优解的和问题不一定是最优的。

这个问题就得划分成很多的子问题,一步步求解即可。

1、输入数据。船的承重w,人数n,用LinkedList存储每个人的质量,这里不用Arraylist的原因不用再解释了。假设测试用例为[w=85,n=6  LinkedList  list = 5 84 85 80 84 83]

2、第一步排序,对所有人的质量进行升序排列,方便后续的操作。

int sn1 =0统计单独做船的船数,int sn2=0统计两个人一条船的船数,int sum=0为所有船的总和。

while(true){

3、list.get(0)是里面最小的数,将这个数与list中的所有数逐个个个求和,剔除超过w  list.get(i) ,统计剔除的个数放在sn1中存储。因为如果和最轻的人的重量都超过w了,那么一定要单独乘坐一辆船。    sn1 = sn1 + 剔除个数

4、剔除list.get(0)  与当前list.get(max) 因为超过w的都已经剔除了,现在的最大重量刚好可以和最轻的坐在一艘船上。最优的步骤解就是让最轻的和相对最重的坐在一艘船上,最大程度的利用这个船。

sn2 = sn2 + 1;

5、判断list.size()==1   说明当前岸上只有一个人,需要船的总个数sum+1,跳出循环。

6、判断list.size()==0   说明刚好分配完,跳出循环。

}

打印sum=sum+sn1+sn2;

其实在实际编程中会遇到,remove的异常,最后发现其实每次在remove的时候都应该判断一下  list.size()==1  sum+1 break;   这样保证程序的健壮性。

代码如下:

import java.util.Collections;import java.util.LinkedList;import java.util.Scanner;public class Main {public static void main(String[] args) {LinkedList<Integer> a = null;Scanner sc = new Scanner(System.in);int N = sc.nextInt();while(N>0){a = new LinkedList<Integer>();int w = sc.nextInt();//承重int n = sc.nextInt();//人的个数for(int i=0;i<n;i++)  //  人数a.add(sc.nextInt());//步骤1Collections.sort(a);//步骤2int n1 = 0;//int n2 = 0;int Sn1 = 0;int Sn2 = 0;int sum = 0;ok:while(true){n1 = n2 = 0;for(int i=1;i<a.size();i++){int tmp = a.get(0)+a.get(i);if(tmp>w){    //步骤3n1 = i;break;}}if(n1!=0){n1 = a.size()-n1;for(int i=1;i<=n1;i++){if(a.size()==1){sum++;break ok;}a.removeLast();     //步骤3之剔除必须单独做船的人}}Sn1 = Sn1 + n1;   //统计剔除单独做船人数的总数if(a.size()==1){   //这种判断是为了让程序减少异常sum++;break;}a.remove();//步骤4if(a.size()==1){sum++;break;}a.removeLast();//步骤4Sn2 = Sn2 + 1;  //步骤4if(a.size()==1){//步骤5sum++;break;}if(a.isEmpty())//步骤6break;}sum = Sn1 + Sn2 + sum;//统计总数System.out.println(sum);N--;}}}






0 0