首页 > 其他分享 >Cf1625C Road Optimization

Cf1625C Road Optimization

时间:2022-12-25 22:11:52浏览次数:61  
标签:路牌 路标 len int Optimization Road include dp Cf1625C

Cf1625C Road Optimization

题意:

在一条长为 \(1\) 的公路上有 \(n\) 个路标,第 \(i\) 个路标在第 \(d_i\) 米处,限速 \(a_i\) ,意味着在这个路标到下一个路标之间的路段最快速度是 \(a\);每公里,现在你最多可以移去k个路标(第一个路标除外,因为移掉之后,最开始的一段路就没有限速了),求通过这条路的最短时间是多少。

数据范围:

\(n \le 500\)

思路:

为了方便可以将终点当成一个路牌。

每个路标有两种可能,删掉或者不删掉。然后因为可以删除k个,所以定义 \(f[i][j]:\) 到第 \(i\) 个路牌,已经删除 \(j\) 个路牌需要通过的最短时间。

$f[i][j] = f[i - 1][j - 1] + $ 上一个存在的路牌的速度 $ * (d_i - d_{i - 1})$。

上一个存在的路牌可能是 \(i - 1\) 到 $ i - j$ 之间 ,这也意味着中间删去了若干个路标,所以就以这若干个路标为划分依据。

转移方程:

//前i个路标
for (int i = 2; i <= n + 1; i++)
    //最多移走p个路标
    for (int p = 0; p <= k; p++)
        //从第j个开始,j + 1到i - 1个都不要
        for (int j = 1; j < i; j++)
        {
            int len = i - j - 1;
            if (p >= len)
                dp[i][p] = min(dp[i][p], dp[j][p - len] + a[j] * (d[i] - d[j]));
        }

实现:

#include <stdio.h>
#include <algorithm>
#include<cstring>
using namespace std;
const int N = 510;
int dp[N][N], d[N], a[N];
int main()
{
    int n, l, k;
    memset(dp,0x3f,sizeof(dp));
    scanf("%d%d%d", &n, &l, &k);
    for (int i = 1; i <= n; i++)
        scanf("%d", &d[i]);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);

    //将终点看作路标
    d[n + 1] = l;
    //第一个路标移不走
    for (int i = 0; i <= k; i++)
        dp[1][i] = 0;

    //前i个路标
    for (int i = 2; i <= n + 1; i++)
        //移走了p个路标
        for (int p = 0; p <= k; p++)
            //从第j个开始,j + 1到i - 1个都不要
            for (int j = 1; j < i; j++)
            {
                int len = i - j - 1;
                if (p >= len)
                    dp[i][p] = min(dp[i][p], dp[j][p - len] + a[j] * (d[i] - d[j]));
            }
    printf("%d\n", dp[n + 1][k]);
    return 0;
}

标签:路牌,路标,len,int,Optimization,Road,include,dp,Cf1625C
From: https://www.cnblogs.com/zxr000/p/17004701.html

相关文章