题目大意:
Smart迷上了溜冰,并准备参加国际溜冰比赛。国际溜冰比赛的赛道长L米。Smart在起点的速度是1米/秒,但他的速度是可以改变的,在每一米的速度可以是前一米的速度加1、减1,或者等于前一米的速度。在滑行的过程中,Smart会遇到N个转弯处,第i个转弯处位于距离出发点D[i]米处。为了安全,Samrt到达第i个转弯处的速度不能超过S[i]米/秒。Smart到达终点时的速度没有最大限制。请你帮忙计算Samrt溜冰过程中最大的速度是多少?
下面的例子,距开始7米处限速为3、11米处限速为1、13米处限速为8,如下图:
解题思路:
先快排然后
一系列骚操作 dp
连续写了好几篇博客,有些累,程序就不写解析了~
转移方程有点长,这里就不写出来了~~
#pragma GCC optimize(3)
#include <cstdio>
#include <algorithm>
using namespace std;
struct node{
int u,w;
} a[100001];
int l,n,maxn;
bool cmp(node x,node y)
{
return x.u<y.u;
}
int main()
{
//freopen("skate.in","r",stdin);
//freopen("skate.out","w",stdout);
scanf("%d%d",&l,&n);
for (int i=1;i<=n;i++)
scanf("%d%d",&a[i].u,&a[i].w);
sort(a+1,a+n+1,cmp);
a[0].w=1;
a[0].u=0;
a[n+1].u=n+1;
a[n+1].w=n;
for (int i=n;i>=2;i--)
a[i-1].w=min(a[i-1].w,a[i].w+a[i].u-a[i-1].u);
for (int i=1;i<=n+1;i++)
{
if (a[i].w-a[i-1].w>=a[i].u-a[i-1].u)
{
if (a[i].w>a[i-1].w+a[i].u-a[i-1].u) {a[i].w=a[i-1].w+a[i].u-a[i-1].u;maxn=max(maxn,a[i].w);}
else {maxn=max(maxn,(int)(a[i].u-a[i-1].u+a[i].w+a[i-1].w)/2);}
}
else
maxn=max(maxn,(int)(a[i].u-a[i-1].u+a[i].w+a[i-1].w)/2);
}
printf("%d",maxn);
}