问题描述
第 i 个人的体重为 people[i],每艘船可以承载的最大重量为 limit。
每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit。
返回载到每一个人所需的最小船数。(保证每个人都能被船载)。
示例 1:
输入:people = [1,2], limit = 3
输出:1
解释:1 艘船载 (1, 2)
示例 2:
输入:people = [3,2,2,1], limit = 3
输出:3
解释:3 艘船分别载 (1, 2), (2) 和 (3)
示例 3:
输入:people = [3,5,3,4], limit = 5
输出:4
解释:4 艘船分别载 (3), (3), (4), (5)
输入说明
首先输入人的数量n,然后输入n个整数,表示人的体重。
最后输入limit。
1 <= n <= 50000
1 <= 人的体重 <= limit <= 30000
输出说明
输出一个整数
输入范例
4
3 5 3 4
5
输出范例
4
实现思路
想要最少的船,也就是让载两人的船尽可能的多。
最主要的思想就是:体重轻的人应该尽量与体重重的人乘一艘船(因为如果不这样的话:比如两个最轻的人一艘船就可能导致其他的人不再有共用一条船的机会,就会导致船的数量变多)
将数据进行排序,排完序后将数据存入双端队列(因为要对收尾进行操作)中。
每一次循环都取首尾两个元素,若两个元素的体重小于limit,则增加一艘船载首尾两元素,然后将首尾两元素弹出队列;若大于limit,则同样增加一艘船载队尾元素,弹出队尾元素。直至队列为空。
实现代码
方法一:用双端队列:
#include<iostream>
#include<vector>
#include<deque>
#include<algorithm>
using namespace std;
class Solution {
public:
int minBoat(vector<int> &weight,int limit) {
int res = 0;
if(weight.size() == 0) return res;
sort(weight.begin(),weight.end());
deque<int>dq;
for(int i = 0;i<weight.size();i++){
dq.push_back(weight[i]);
}
while(!dq.empty()){
if(!dq.empty() && ((dq.front() + dq.back()) <= limit)){
res++;
if(dq.size()==1){//处理队列只有一个元素的特殊情况,防止指针错误
dq.pop_back();
}else{
dq.pop_front();
dq.pop_back();
}
}else if(!dq.empty() && ((dq.front() + dq.back()) > limit)){
res++;
dq.pop_back();
}
}
return res;
}
};
int main()
{
int n,data,limit;
vector<int> weight;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>data;
weight.push_back(data);
}
cin>>limit;
int res=Solution().minBoat(weight,limit);
cout<<res;
return 0;
}
方法二:
class Solution {
public:
int minBoat(vector<int> &weight,int limit) {
int res = 0;
if(weight.size() == 0) return res;
sort(weight.begin(),weight.end());
int wfront = 0;
int wback = weight.size() - 1;
while(wfront <= wback){
if(weight[wfront] + weight[wback] > limit){
wback--;
}else{
wback--;
wfront++;
}
res++;
}
return res;
}
};