你驾驶出租车行驶在一条有 n 个地点的路上。这 n 个地点从近到远编号为 1 到 n ,你想要从 1 开到 n ,通过接乘客订单盈利。你只能沿着编号递增的方向前进,不能改变方向。
乘客信息用一个下标从 0 开始的二维数组 rides 表示,其中 rides[i] = [starti, endi, tipi] 表示第 i 位乘客需要从地点 starti 前往 endi ,愿意支付 tipi 元的小费。
每一位 你选择接单的乘客 i ,你可以 盈利 endi - starti + tipi 元。你同时 最多 只能接一个订单。
给你 n 和 rides ,请你返回在最优接单方案下,你能盈利 最多 多少元。
注意:你可以在一个地点放下一位乘客,并在同一个地点接上另一位乘客。
示例 1:
输入:n = 5, rides = [[2,5,4],[1,5,1]]
输出:7
解释:我们可以接乘客 0 的订单,获得 5 - 2 + 4 = 7 元。
示例 2:
输入:n = 20, rides = [[1,6,1],[3,10,2],[10,12,3],[11,12,2],[12,15,2],[13,18,1]]
输出:20
解释:我们可以接以下乘客的订单:
提示:
1 <= n <= 105
1 <= rides.length <= 3 * 104
rides[i].length == 3
1 <= starti < endi <= n
1 <= tipi <= 105
先贪心的角度,按每个订单结束的地点由小到大排序,其次再排序,努力找之前的订单中能获得的最大值。
AC代码
class Solution {
public:
typedef long long ll;
struct Node
{
int start;
int end;
int tip;
}a[30005];
static int cmp(Node a1,Node a2)
{
if(a1.end<a2.end)return true;
if(a1.end==a2.end)
{
if(a1.start<a2.start)return true;
if(a1.start==a2.start)return a1.tip<a2.tip;
}
return false;
}
vector<vector<ll>>q;
void Update(vector<ll>x)
{
if(q.empty())
q.push_back(x);
else
{
int n=q.size()-1;
while(q.size()>0&&q[n][0]>=x[0]&&q[n][1]<=x[1])
{
q.pop_back();
n=q.size()-1;
}
if(q.empty())
q.push_back(x);
else if(x[0]>=q[n][0]&&x[1]>q[n][1])
q.push_back(x);
}
}
ll search(int st)
{
if(q.size()==0)return 0;
int l=0,r=q.size()-1;
ll res=0;
while(l<=r)
{
int mid=(l+r)/2;
if(q[mid][0]<=st)
{
res=q[mid][1];
l=mid+1;
}
else r=mid-1;
}
//cout<
return res;
}
long long maxTaxiEarnings(int n, vector<vector<int>>& rides)
{
for(int i=0;i<rides.size();i++)
{
a[i].start=rides[i][0];
a[i].end=rides[i][1];
a[i].tip=rides[i][2];
}
sort(a,a+rides.size(),cmp);
//for(int i=0;i
//cout<
ll res=0;
for(int i=0;i<rides.size();i++)
{
ll back = search(a[i].start)+(a[i].end-a[i].start+a[i].tip);
//cout<
res=max(res,back);
vector<ll>x;
x.push_back(a[i].end);
x.push_back(back);
Update(x);
}
return res;
}
};