Problem
给出一个初始速度v1,结束速度v2,时间t以及每个单位时间速度的最大变化量。
求t个单位时间内的最大行驶距离。
Solution
我们可以发现,肯定是最先开始尽量加速度,最后在减下来,这样的方案才是最优的。
1.可以O(n)求出加速度,减速度,然后找到临界点计算时间。
2.可以O(1)求出两速度变化直线的交点,然后用等差数列求和公式求出和。
Notice
d等于0时要特判,不然分母会变成0。
Code
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define sqz main
#define ll long long
#define reg register int
#define rep(i, a, b) for (reg i = a; i <= b; i++)
#define per(i, a, b) for (reg i = a; i >= b; i--)
#define travel(i, u) for (reg i = head[u]; i; i = edge[i].next)
const int INF = 1e9;
const double eps = 1e-6, phi = acos(-1);
ll mod(ll a, ll b) {if (a >= b || a < 0) a %= b; if (a < 0) a += b; return a;}
ll read(){ ll x = 0; int zf = 1; char ch; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') zf = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;}
void write(ll y) { if (y < 0) putchar('-'), y = -y; if (y > 9) write(y / 10); putchar(y % 10 + '0');}
int sqz()
{
int v1 = read(), v2 = read(), t = read(), d = read();
if (d == 0)
{
printf("%d\n", v1 * t);
return 0;
}
int pos = (d * (t + 1) + v2 - v1) / (2 * d);
int dis1 = v1 * pos + d * pos * (pos - 1) / 2, dis2 = v2 * (t - pos) + d * (t - pos) * (t - pos - 1) / 2;
printf("%d\n", dis1 + dis2);
return 0;
}