G - Optimal Biking Strategy(DP + 二分)
F[i][j]表示到第i个车站花费不超过j元骑行的最大距离
当前是不超过j元,该状态可以由第id个车站更新而来,花费为cost
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 1e6 + 10;
int a[N], k;
int f[N][10];
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n, p, s;
cin >> n >> p >> s;
for (int i = 1; i <= n; i ++ ) {
cin >> a[i];
}
cin >> k;
for (int i = 1; i <= n; i ++ ) {
for (int j = 1; j <= k; j ++ ) {
f[i][j] = f[i - 1][j];
//这个地方要找i这一层的关系,自己体会
//这个地方更新的逻辑是,如果当前状态无法从下面的状态更新过来,他继承的是哪个状态
for (int cost = 1; cost <= j; cost ++ ) {
int mx = cost * s;
//a[i] - a[id] <= mx
// a[id] >= a[i] - mx
int id = lower_bound(a + 1, a + n + 1, a[i] - mx) - a;
if(id == n + 1)continue;
f[i][j] = max(f[i][j], f[id][j - cost] + a[i] - a[id]);
}
}
}
//所以最后找答案直接找f[i][k]就行,你细品,k是j中某个特殊的值
int ans = -1;
for (int i = 1; i <= n; i ++ ) ans = max(ans, f[i][k]);
cout << (p - ans) << '\n';
return 0;
}