CF 1625C - Road Optimization
题目链接:
https://codeforces.com/problemset/problem/1625/C
题目大意:
在一条长为 \(l\) 的公路上有 \(n\) 个路标,第 \(i\) 个路标在第 \(d_i\) 米处,限速 \(a_i\),意味着在这个路标到下一个路标之间的路段最快速度是 \(a_i\) 每公里,现在你最多可以移去 \(k\) 个路标(第一个路标除外,因为移掉之后,最开始的一段路就没有限速了),求通过这条路的最短时间是多少。
思路:
看一下数据范围,500,再结合题意,可以想到通过 \(dp\) 来解。
\(dp_{i, j}\) 表示在前 \(i\) 个路标中移去 \(j\) 个路标后走完这段所花的最短的时间。
代码:
#include
using namespace std;
const int N = 510;
int f[N][N], d[N], a[N], n, l, k;
void solve(){
cin >> n >> l >> k;
memset(f, 0x3f, sizeof(f));
for (int i = 1; i <= n; i++)
cin >> d[i];
for (int i = 1; i <= n; i++)
cin >> a[i];
d[n + 1] = l; //最后需要到 l
for (int i = 0; i <= k; i++)
f[1][i] = 0; //因为第一个路标移不了,所以初始化为 0
for (int i = 2; i <= n + 1; i++) //前 i 个路标
for (int p = 0; p <= k; p++) //移走了 p 个路标
for (int j = 1; j < i; j++){ //从第 j 个开始移,将第 j + 1 个到第 i - 1 个都移走
int len = i - j - 1;
if (p >= len)
f[i][p] = min(f[i][p], f[j][p - len] + a[j] * (d[i] - d[j]));
}
cout << f[n + 1][k] << "\n";
}
int main(){
solve();
return 0;
}