题目链接:codeforces 1625C
题目思路:
定义 dp[i][j] 为终点为
i
i
i,选中
j
j
j 个点所需要的最少时间。状态转移方程:
d
p
[
i
]
[
j
]
=
m
i
n
(
d
p
[
i
]
[
j
]
,
d
p
[
u
]
[
j
−
(
i
−
u
−
1
)
]
+
a
[
u
]
∗
(
d
[
i
]
−
d
[
u
]
)
)
dp[i][j] = min(dp[i][j], dp[u][j-(i-u-1)] + a[u] * (d[i] - d[u]))
dp[i][j]=min(dp[i][j],dp[u][j−(i−u−1)]+a[u]∗(d[i]−d[u]))
其中
u
u
u 为 前
i
−
1
i - 1
i−1 个中的任意节点。方程表示,每次选中的
j
j
j 个点是在
2
2
2~
u
−
1
u-1
u−1 中,而不在
u
u
u~
i
i
i 中,不断枚举更新,最后求的的答案是 dp[n+1][k]。
参考代码:
#include <iostream>
#incldue <cstring>
using namespace std;
const int maxn = 550;
int a[maxn], d[maxn], dp[maxn][maxn];
int main() {
int n, l, k;
cin >> n >> l >> k;
for (int i = 1; i <= n; i++) cin >> d[i];
d[n+1] = l;
for (int i = 1; i <= n; i++) cin >> a[i];
memset(dp, 0x3f, sizeof dp);
for (int i = 0; i <= k; i++) dp[1][i] = 0;
for (int i = 2; i <= n+1; i++) {
for (int j = 0; j <= k; j++) {
for (int u = 1; u < i; u++) {
if (j - (i-u-1) < 0) continue;
dp[i][j] = min(dp[i][j], dp[u][j-(i-u-1)] + a[u] * (d[i] - d[u]));
}
}
}
cout << dp[n+1][k] << endl;
return 0;
}
博客详细介绍了如何解决codeforces上的1625C问题,利用线性动态规划(DP)方法来优化道路。通过定义状态转移方程dp[i][j],表示到达位置i时选择j个点的最短时间,通过枚举前i-1个节点进行更新,最终找到最优解。
&spm=1001.2101.3001.5002&articleId=122482315&d=1&t=3&u=5dc8b463a9494f59ac92c9b742b3a5bc)
1042

被折叠的 条评论
为什么被折叠?



