0
点赞
收藏
分享

微信扫一扫

【Codeforces】1625C Road Optimization 题解

夏沐沐 2022-02-04 阅读 63

题目大意

两个城市相聚 l l l千米,要从起点城市通过一条路到达目标城市,路上有 n n n个限速点(第一个限速点在起点),每个限速点位置在 d i d_i di,值为 b i b_i bi,表示从这个限速点到下个限速点位置,每经过一千米需要花费 b i b_i bi点单位时间。

你可以删掉不超过 k k k个限速点,请问删除后到达目标城市的最短时间是多少?

思路

A A A限速点到达 B B B限速点所需时间与怎么到 A A A没有关系,只于还有多少删除机会有关。

进一步讲,到达 A A A点肯定是从 A A A点前某一个点来的,到达 A A A点之后,就和它没关系了,所以我们想到了动态规划来解决这个问题。

d p [ i ] [ j ] dp[i][j] dp[i][j]表示从起点到达 i i i号限速点,并用掉了 j j j次删除机会,所能达到的最短时间。

我们从这个点往后走,那么有 d p [ i + c n t ] [ j + c n t − 1 ] = m i n ( d p [ i + c n t ] [ j + c n t − 1 ] , d p [ i ] [ j ] + ( d [ i + c n t ] − d [ i ] ) ∗ b [ i ] ) , 其 中 j + c n t − 1 ≤ k dp[i+cnt][j+cnt-1] = min(dp[i+cnt][j+cnt-1], dp[i][j] + (d[i+cnt]-d[i]) * b[i]),其中j+cnt-1 \le k dp[i+cnt][j+cnt1]=min(dp[i+cnt][j+cnt1],dp[i][j]+(d[i+cnt]d[i])b[i]),j+cnt1k

代码

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

const int maxN = 505, INF = 0x3f3f3f3f;

int dp[maxN][maxN], n, l, k, b[maxN], d[maxN];

int main()
{
    scanf("%d%d%d", &n, &l, &k);
    for(int i = 0; i < n; ++i)
        scanf("%d", &d[i]);
    for(int i = 0; i < n; ++i)
        scanf("%d", &b[i]);
    memset(dp, 0x3f, sizeof dp);
    dp[0][0] = 0; d[n] = l;
    for(int i = 1; i <= n; ++i)
        dp[i][0] = dp[i - 1][0] + b[i - 1] * (d[i] - d[i - 1]);
    for(int i = 0; i < n; ++i)
        for(int j = 0; j <= k; ++j) 
            for(int pos = i + 1; pos <= n; ++pos)
                dp[pos][j + pos - i - 1] = min(dp[pos][j + pos - i - 1], dp[i][j] + b[i] * (d[pos] - d[i]));
    int ans = INF;
    for(int i = 0; i <= k; ++i)
        ans = min(ans, dp[n][i]);
    printf("%d\n", ans);
    return 0;
}
举报

相关推荐

0 条评论