NYOJ-71 独木舟上的旅行

独木舟上的旅行

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

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

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

这道题跟装箱问题差不多,可以采用脱机下的首次适配法。将所有体重从大到小排序,然后对于每一个乘客,将其放入第一个能容下该乘客的独木舟(以下称船)。这是一般情况,可是本题有个陷阱,每条船只能乘坐两个人,这样,只要在寻找第一个能容下该乘客的船的时候判断一下该船是否满员即可。

#include <iostream>
02. #include <algorithm>
03. #include <vector>
04. using namespace std;
05.  
06. #define maxn 302
07.  
08. int w[maxn];
09. int ww[maxn][2];
10.  
11. int main()
12. {
13. int s,W,n,count;
14. cin>>s;
15. while(s--)
16. {
17. cin>>W>>n;
18. for(int i=0;i<n;i++)
19. cin>>w[i];
20. for(int i=0;i<n;i++)
21. {
22. ww[i][0]=W;
23. ww[i][1]=0;
24. }
25. sort(w,w+n,greater<int>());
26. for(int i=0;i<n;i++)
27. {
28. for(int j=0;j<n;j++)
29. {
30. if(w[i]<=ww[j][0]&&ww[j][1]<2)
31. {
32. ww[j][0]-=w[i];
33. ww[j][1]++;
34. break;
35. }
36. }
37. }
38. count=0;
39. for(int i=0;i<n;i++)
40. if(ww[i][0]<W)
41. count++;
42. cout<<count<<endl;
43. }
44. return 0;
45. }


上面这个是一般方法,但本题由于有每条船只能容两人的条件,所以可以有更特别的方法。

a 首先,所有的乘客都有重量,也按重量从大到小排序。

b 依次处理,首先判断该乘客是否有重量,若有重量则为其分配一条船,将该乘客重量置0,并用这条船剩下的容量去寻找后面能容下的第一个乘客,也是最重的乘客,并将该乘客重量置0,此时该船已经容下两个人了,该船没用了。若没有重量则处理下一个乘客

c 然后重重复步骤b,直到所有人都处理完。


01. #include <iostream>
02. #include <algorithm>
03. #include <vector>
04. using namespace std;
05.  
06. #define maxn 302
07.  
08. int w[maxn];
09.  
10. int main()
11. {
12. int s,W,n,count;
13. cin>>s;
14. while(s--)
15. {
16. cin>>W>>n;
17. for(int i=0;i<n;i++)
18. cin>>w[i];
19. sort(w,w+n,greater<int>());
20. int tw;
21. count=0;
22. for(int i=0;i<n;i++)
23. {
24. tw=W;
25. if(w[i]!=0)
26. {
27. count++;
28. tw-=w[i];
29. for(int j=i+1;j<n;j++)
30. {
31. if(w[j]!=0&&w[j]<=tw)
32. {
33. w[j]=0;
34. break;
35. }
36. }
37. }
38. }
39. cout<<count<<endl;
40. }
41. return 0;
42. }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值