中文链接:洛谷P4266
题目大意:
Farmer John和他的私人教练Bessie正在徒步攀登温哥牛山。
基于他们的目的(也是你的目的),这座山可以用一条长为L米的长直路径表示。Farmer John会沿着这条路径以每米rF 秒的固定速度攀登。由于他正在训练他的耐力,他在途中不会进行任何的休息。 然而Bessie可以在休息站休息,在那里她能够找到一些美味的嫩草。当然,她也不能在任何地方都休息!在路径上总共有N个休息站;第i个休息站距离路径的起点xi米,有美味值为ci的草。如果Bessie在休息站ii休息了t秒,她能够得到ci*t个美味单位。不在休息站的时候,Bessie会以每米rB秒的固定速度攀登。由于Bessie年轻而健康,rF严格小于rB
Bessie想要吃到最多的美味嫩草。然而她也担心Farmer John;她认为如果在任何时候她位于Farmer John身后,Farmer John可能就会失去前进的动力了!
帮助Bessie求出,在确保Farmer John能够完成登山的情况下,她能够获得的最多的美味单位。
数据大小:
路的长度:L(1<=L<=106)
速度:r (1<=rF < rB<=106)
美味值:ci(1<=ci<=106)
休息站:N(1<=N<=105)
思路:
贪心算法。
很显然我们想让Bessie获得更多的美味值,那么就得尽量在ci值较大的地方尽可能地停留更多的时间t(xi*(rF-rB)),如下图所示,很显然,当我们在xi = 7处停留,那么在1 – 7之间来说,美味值是最高的选择!(获得的美味值可以看成是ci的高度乘以到t的面积)
所以我们可以先把美味值按从大到小排序,相等美味值则位置远的优先。
然后放入队列中,先跑到第一个(也就是美味值最大的地方),等到John也到的时候就跑到下一个美味值最大的点,如果下一个的位置xi已经过去了,就弹出队列。队列为空时结束,输出答案即可。
ac丑代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include <vector>
#include<algorithm>
using namespace std;
typedef long long ll;
#define MAX 100005
#define INF 10000000
struct dot{
int x;
int c;
}d[MAX];
bool cmp(dot a,dot b)
{
if(a.c>b.c)return 1;
else if(a.c == b.c)
{
if(a.x < b.x)return 1;
}
return 0;
}
int main()
{
ll l,n,Ra,Rb;
ll sum = 0;
scanf("%lld %lld %lld %lld",&l,&n,&Ra,&Rb);
for(int i = 0;i<n;i++)
{
scanf("%d %d",&d[i].x,&d[i].c);
}
sort(d,d+n,cmp);
int now = 0;
for(int i = 0;i<n;i++)
{
if(d[i].x < now)continue;
ll t = (Ra-Rb)*(d[i].x - now);//可以停留的时间
now = d[i].x;
sum+=t*d[i].c;
}
printf("%lld",sum);
return 0;
}